哈希相同的字符串和相同的盐给出不同的哈希结果
Hashing same string and same salt giving different hash result
我正在尝试使用 Microsoft Docs Hashing 中的代码来散列密码并将其存储在数据库中。保存哈希和盐可以正常工作。
我的哈希方法:
public Tuple<string,string> PasswordCrypting(string password)
{
byte[] salt = new byte[128 / 8];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(salt);
}
string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: password,
salt:salt,
prf: KeyDerivationPrf.HMACSHA1,
iterationCount: 10000,
numBytesRequested: 256 / 8));
Tuple<string, string> credentials = new Tuple<string, string>(hashed, Convert.ToBase64String(salt));
return credentials;
}
在用户登录时,我从数据库中检索盐,并使用它使用用户输入的密码和盐重新创建散列。我会使用我得到的哈希值与存储在数据库中的哈希值进行比较。
public string PasswordDecrypting(string username,string password)
{
string salt = _userManager.GetPassSalt(username);
string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: password,
salt: Convert.FromBase64String(salt),
prf: KeyDerivationPrf.HMACSHA1,
iterationCount: 10000,
numBytesRequested: 256 / 8));
return hashed;
}
问题是我永远无法获得与数据库中相同的哈希值。我调试了我的代码,salt 与数据库中的匹配,密码字符串与第一次散列时相同;使用相同的算法,但生成的哈希值与我应该得到的不同。
这个算法是这样设计的,所以它永远不会生成相同的哈希值,如果是这样,我该如何重新创建我的哈希值?
我已经创建了一个单元测试来测试您的代码。并且必须得出您没有正确存储盐的结论,或者您在存储之前或从数据库中检索盐之后以某种方式更改了盐。
我写了下面的单元测试:
[TestMethod]
public void Test_SaltGeneration()
{
var password = "48F3A112-F574-4B25-B226-CE97888FCBCB";
var firstResult = PasswordCrypting(password);
var secondResult = PasswordDecrypting(password, firstResult.salt);
Assert.IsTrue(firstResult.hash.Equals(secondResult));
}
public (string hash, string salt) PasswordCrypting(string password)
{
byte[] salt = new byte[128 / 8];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(salt);
}
string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: password,
salt: salt,
prf: KeyDerivationPrf.HMACSHA1,
iterationCount: 10000,
numBytesRequested: 256 / 8));
return (hashed, Convert.ToBase64String(salt));
}
public string PasswordDecrypting(string password, string salt )
{
string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: password,
salt: Convert.FromBase64String(salt),
prf: KeyDerivationPrf.HMACSHA1,
iterationCount: 10000,
numBytesRequested: 256 / 8));
return hashed;
}
如您所料。这个测试通过。暗示我的第一个断言。
我正在尝试使用 Microsoft Docs Hashing 中的代码来散列密码并将其存储在数据库中。保存哈希和盐可以正常工作。 我的哈希方法:
public Tuple<string,string> PasswordCrypting(string password)
{
byte[] salt = new byte[128 / 8];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(salt);
}
string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: password,
salt:salt,
prf: KeyDerivationPrf.HMACSHA1,
iterationCount: 10000,
numBytesRequested: 256 / 8));
Tuple<string, string> credentials = new Tuple<string, string>(hashed, Convert.ToBase64String(salt));
return credentials;
}
在用户登录时,我从数据库中检索盐,并使用它使用用户输入的密码和盐重新创建散列。我会使用我得到的哈希值与存储在数据库中的哈希值进行比较。
public string PasswordDecrypting(string username,string password)
{
string salt = _userManager.GetPassSalt(username);
string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: password,
salt: Convert.FromBase64String(salt),
prf: KeyDerivationPrf.HMACSHA1,
iterationCount: 10000,
numBytesRequested: 256 / 8));
return hashed;
}
问题是我永远无法获得与数据库中相同的哈希值。我调试了我的代码,salt 与数据库中的匹配,密码字符串与第一次散列时相同;使用相同的算法,但生成的哈希值与我应该得到的不同。
这个算法是这样设计的,所以它永远不会生成相同的哈希值,如果是这样,我该如何重新创建我的哈希值?
我已经创建了一个单元测试来测试您的代码。并且必须得出您没有正确存储盐的结论,或者您在存储之前或从数据库中检索盐之后以某种方式更改了盐。
我写了下面的单元测试:
[TestMethod]
public void Test_SaltGeneration()
{
var password = "48F3A112-F574-4B25-B226-CE97888FCBCB";
var firstResult = PasswordCrypting(password);
var secondResult = PasswordDecrypting(password, firstResult.salt);
Assert.IsTrue(firstResult.hash.Equals(secondResult));
}
public (string hash, string salt) PasswordCrypting(string password)
{
byte[] salt = new byte[128 / 8];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(salt);
}
string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: password,
salt: salt,
prf: KeyDerivationPrf.HMACSHA1,
iterationCount: 10000,
numBytesRequested: 256 / 8));
return (hashed, Convert.ToBase64String(salt));
}
public string PasswordDecrypting(string password, string salt )
{
string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: password,
salt: Convert.FromBase64String(salt),
prf: KeyDerivationPrf.HMACSHA1,
iterationCount: 10000,
numBytesRequested: 256 / 8));
return hashed;
}
如您所料。这个测试通过。暗示我的第一个断言。