3

I am using the following code to hash passwords using Pbkdf2:

private string HashPassword(string password)
        {
            // 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));

            return hashedPassword;
        }

How do I verify the password for authentication? It seems I need to get the salt used to hash the password. How do I get that? Please note that I am not using a separate field to store the hash. Only the hashed password is stored in the database.

Clairvoyant
  • 81
  • 1
  • 9
  • 2
    The normal approach is to prepend the salt onto the hash, and store the whole thing in the database. When you come to authenticate someone, split the salt from the hash. It's also common to add 1) an identifier for the hash algorithm used, 2) the number of iterations, so you can change these in the future while retaining backwards compatibility. – canton7 Nov 04 '19 at 12:19
  • How do I separate these? Can I use something like a dot (.)? What if the hash contains a dot? – Clairvoyant Nov 04 '19 at 12:20
  • 2
    One approach is to encode the salt and hash as hex or base64 strings, and use a non-base-64 character such as a dollar sign `$` or colon `:` as the separator. See [bcrypt for example](https://en.wikipedia.org/wiki/Bcrypt) – canton7 Nov 04 '19 at 12:23
  • @canton7 Thanks alot. I couldn't figure this out after reading many tutorials. – Clairvoyant Nov 04 '19 at 12:40
  • Did you accept to store salt to database?For the salt is generated by random,you need to store it in database then you could verify the password. – Rena Nov 06 '19 at 02:04

1 Answers1

2

One possible alternative could be to use PasswordHasher from Microsoft.AspNet.Identity on following way.

var passwordHasher = new PasswordHasher();
var pass = "password";
var hash = passwordHasher.HashPassword(pass);
var isVerified = passwordHasher.VerifyHashedPassword(hash, pass) 
              != PasswordVerificationResult.Failed;
Console.WriteLine((isVerified ? "Verified" : "Not verified"));
  • 1
    How do you know the PasswordHasher from Microsoft.AspNet.Identity uses the PBKDF2 hashing algorithm? You can also use any other hashing algorithm which takes no salt. Only it will be less secure ... – René Heuven Jun 30 '22 at 12:20
  • @René Heuven, I was getting the idea from the source. Here it is, https://github.com/aspnet/AspNetIdentity/blob/b7826741279450c58b230ece98bd04b4815beabf/src/Microsoft.AspNet.Identity.Core/Crypto.cs Thanks for your additional information – Nayeem Bin Ahsan Aug 19 '22 at 09:26