Reputation: 13895
I am using the following code to created a hashed password and 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));
I am storing the HashedPassword and Salt in the database.
Now I want to verify the password on User Login:
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;
}
This is not working, I am getting a completely different hashed password than the one stored in the database. From what I understand you are supposed to prepend the salt to the password that the user enters when logging in and then run the same Hash Password function. Wouldn't the above be the equivalent to that?
Upvotes: 2
Views: 2637
Reputation: 678
Create a salt with the bellow code:
byte[] salt = new byte[128 / 8];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(salt);
}
return Convert.ToBase64String(salt);
Then create a hashed password using that salt.
string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: password,
salt: salt,
prf: KeyDerivationPrf.HMACSHA1,
iterationCount: 10000,
numBytesRequested: 256 / 8));
Save the salt that used in somewhere (ex: database) Save the hashed password for that user.
Upvotes: 1
Reputation: 63
As Maarten Bodewes mentioned, ASCII was the problem. The code below returns true. All I changed was salt: Encoding.ASCII.GetBytes(dbPasswordSalt),
to 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;
}
Upvotes: 1