大家好我正在尝试匹配我使用的PHP登录系统
define('PASSWORD_ENCRYPTION', "bcrypt");
define('PASSWORD_SHA512_ITERATIONS', 25000);
define('PASSWORD_BCRYPT_COST', "13");
define('PASSWORD_SALT', "/8Wncr26eAmxD1l6cAF9F8"); //22 characters to be appended on first 7 characters that will be generated using PASSWORD_ info above
Run Code Online (Sandbox Code Playgroud)
我的C#:
string myPassword = this.password_txt.Text;
string mySalt = "$2a$13$/8Wncr26eAmxD1l6cAF9F8";
string hashed = BCrypt.HashPassword(myPassword, mySalt);
Run Code Online (Sandbox Code Playgroud)
问题:我使用C#编写的哈希密码与数据库上的登录PHP哈希密码不匹配...
你的全部功能看起来像这样
/**
* Hash given password.
* @param string $password Unhashed password.
* @return string Hashed password.
*/
public function hashPassword($password) {
//this salt will be used in both algorithms
//for bcrypt it is required to look like this,
//for sha512 it is not required but it can be used
$salt = "$2a$" . PASSWORD_BCRYPT_COST . "$" . PASSWORD_SALT;
if(PASSWORD_ENCRYPTION == "bcrypt") {
$newPassword = crypt($password, $salt);
}
else {
$newPassword = $password;
for($i=0; $i<PASSWORD_SHA512_ITERATIONS; $i++)
$newPassword = hash('sha512',$salt.$newPassword.$salt);
}
return $newPassword;
}
Run Code Online (Sandbox Code Playgroud)
编辑:更多的研究表明,$2a$这似乎BlowFish Encryption来自研究.(http://php.net/crypt)
CRYPT_BLOWFISH - 带有盐的河豚散列如下:"$ 2a $","$ 2x $"或"$ 2y $",两位数的成本参数"$",字母表中的22个字符"./0-9A -za-Z".在salt中使用此范围之外的字符将导致crypt()返回零长度字符串.两位数的成本参数是底层基于Blowfish的散列算法的迭代计数的基数2对数,并且必须在04-31范围内,超出此范围的值将导致crypt()失败.5.3.7之前的PHP版本仅支持"$ 2a $"作为salt前缀:PHP 5.3.7引入了新的前缀来修复Blowfish实现中的安全漏洞.有关安全修复程序的完整详细信息,请参阅»此文档,但总而言之,仅针对PHP 5.3.7及更高版本的开发人员应使用"$ 2y $"优先于"$ 2a $".
它必须以"$ 2",可选"a","$",两位数字,"$"和22位64位数字开头.字符串的其余部分将被忽略.可选"a"的存在意味着在将密码用作密钥之前将NUL附加到密码.两位数设置成本参数.22个基本64位数字编码盐.
$13$被称为cost.(循环加密多少次).现在,盐本身已编码base64,您必须在使用之前对其进行解码Eksblowfish
Eksblowfish,状态为(昂贵的关键时间表河豚,是河豚块密码的成本可参数化和盐渍变化.)
无论如何总结一下,你必须使用这个
http://bcrypt.codeplex.com/
这应该是这样的
int PASSWORD_BCRYPT_COST = 13;
string PASSWORD_SALT = "/8Wncr26eAmxD1l6cAF9F8";
string salt = "$2a$" + PASSWORD_BCRYPT_COST + "$" + PASSWORD_SALT;
string password "test123abc";
var hash = BCrypt.HashPassword(password, salt);
textBox1.Text = hash;
Run Code Online (Sandbox Code Playgroud)
密码= test123abc
输出为textbox1:$2a$13$/8Wncr26eAmxD1l6cAF9FuVnazDlahXc73He5NB1GKNYG7v3mOOyS

还在php http://ideone.com/8piXMq中运行你的代码
php输出
echo hashPassword("test123abc");
Run Code Online (Sandbox Code Playgroud)
php的输出是: $2a$13$/8Wncr26eAmxD1l6cAF9FuVnazDlahXc73He5NB1GKNYG7v3mOOyS
C#
$2a$13$/8Wncr26eAmxD1l6cAF9FuVnazDlahXc73He5NB1GKNYG7v3mOOyS
PHP
$2a$13$/8Wncr26eAmxD1l6cAF9FuVnazDlahXc73He5NB1GKNYG7v3mOOyS
正如您所看到的,答案都是IDENTICAL
从BCrypt HashPassword实现中可以看出,它解码了base64 salt并使用您指定的salt重新加密新密码.
/// <summary>
/// Hash a password using the OpenBSD bcrypt scheme.
/// </summary>
/// <param name="password">The password to hash.</param>
/// <param name="salt">The salt to hash with (perhaps generated
/// using <c>BCrypt.GenerateSalt</c>).</param>
/// <returns>The hashed password.</returns>
public static string HashPassword(string password, string salt) {
if (password == null) {
throw new ArgumentNullException("password");
}
if (salt == null) {
throw new ArgumentNullException("salt");
}
char minor = (char)0;
if (salt[0] != '$' || salt[1] != '2') {
throw new ArgumentException("Invalid salt version");
}
int offset;
if (salt[1] != '$') {
minor = salt[2];
if (minor != 'a' || salt[3] != '$') {
throw new ArgumentException("Invalid salt revision");
}
offset = 4;
} else {
offset = 3;
}
// Extract number of rounds
if (salt[offset + 2] > '$') {
throw new ArgumentException("Missing salt rounds");
}
int rounds = Int32.Parse(salt.Substring(offset, 2), NumberFormatInfo.InvariantInfo);
byte[] passwordBytes = Encoding.UTF8.GetBytes(password + (minor >= 'a' ? "\0" : String.Empty));
byte[] saltBytes = DecodeBase64(salt.Substring(offset + 3, 22),
BCRYPT_SALT_LEN);
BCrypt bcrypt = new BCrypt();
byte[] hashed = bcrypt.CryptRaw(passwordBytes, saltBytes, rounds);
StringBuilder rs = new StringBuilder();
rs.Append("$2");
if (minor >= 'a') {
rs.Append(minor);
}
rs.Append('$');
if (rounds < 10) {
rs.Append('0');
}
rs.Append(rounds);
rs.Append('$');
rs.Append(EncodeBase64(saltBytes, saltBytes.Length));
rs.Append(EncodeBase64(hashed,
(bf_crypt_ciphertext.Length * 4) - 1));
return rs.ToString();
}
Run Code Online (Sandbox Code Playgroud)