Does this look like a good method to hash a user password? I'm not very familiar with how this whole hashing process works and below is a bunch of stuff I've seen on many different posts.
My main concern are all of the numbers. Do they all need to match? Do they need to match something like the array.copy
?
And then the array.copy
lines. I just want to try and understand it better before I move forward with it further.
public const int SALT_BYTE_SIZE = 16;
public const int HASH_BYTE_SIZE = 20;
[ChildActionOnly]
private static void CreateHash(string password)
{
// Generate Random Salt
RNGCryptoServiceProvider csprng = new RNGCryptoServiceProvider();
byte[] salt = new byte[SALT_BYTE_SIZE];
csprng.GetBytes(salt);
// hash value
var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 10000);
byte[] hash = pbkdf2.GetBytes(20);
// combine salt + hash
byte[] hashBytes = new byte[HASH_BYTE_SIZE];
Array.Copy(salt, 0, hashBytes, 0, 16);
Array.Copy(hash, 0, hashBytes, 16, 20);
// Convert hash into string to DB storage
string savedPasswordHash = Convert.ToBase64String(hashBytes);
// save to DB
}
RNGCryptoServiceProvider
andRfc2898DeriveBytes
implementIDisposable
, so you should be wrapping each of their lifetimes inusing
statements. \$\endgroup\$Rfc2898DeriveBytes
has a built in salt generator. \$\endgroup\$hashBytes
is an unfortunate name since it contains more than justhash
. This amalgamation is generally calleddigest
. \$\endgroup\$