我使用以下代码创建哈希密码和salt:
// generate a 128-bit salt using a secure PRNG
byte[] salt = new byte[128 / 8];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(salt);
}
// derive a 256-bit subkey (use HMACSHA1 with 10,000 iterations)
string hashedPassword = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: password,
salt: salt,
prf: KeyDerivationPrf.HMACSHA1,
iterationCount: 10000,
numBytesRequested: 256 / 8));
我将HashedPassword和Salt存储在数据库中。
现在我想在用户登录时验证密码:
public bool VerifyPassword(string userEnteredPassword, string dbPasswordHash, string dbPasswordSalt)
{
string hashedPassword = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: userEnteredPassword,
salt: Encoding.ASCII.GetBytes(dbPasswordSalt),
prf: KeyDerivationPrf.HMACSHA1,
iterationCount: 10000,
numBytesRequested: 256 / 8));
return dbPasswordHash == hashedPassword;
}
这不起作用,我得到一个完全不同的哈希密码,而不是存储在数据库中的密码。根据我的理解,您应该将salt添加到用户登录时输入的密码,然后运行相同的Hash密码功能。以上不等于那个吗?
正如Maarten Bodewes所说,ASCII就是问题所在。以下代码返回true。所有我改变的是salt: Encoding.ASCII.GetBytes(dbPasswordSalt),
到salt: System.Convert.FromBase64String(dbPasswordSalt),
public bool VerifyPassword(string userEnteredPassword, string dbPasswordHash, string dbPasswordSalt)
{
Console.WriteLine(dbPasswordSalt.ToString());
Console.WriteLine(dbPasswordHash.ToString());
string hashedPassword = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: userEnteredPassword,
salt: System.Convert.FromBase64String(dbPasswordSalt),///Encoding.ASCII.GetBytes(dbPasswordSalt),
prf: KeyDerivationPrf.HMACSHA1,
iterationCount: 10000,
numBytesRequested: 256 / 8));
Console.WriteLine(hashedPassword.ToString());
return dbPasswordHash == hashedPassword;
}