I am new to C# and this is my first question here so I apologize in advance for any faux pas.
Context:
When a user registers I call the CreateSaltedHash() method and pass it the user inputted password from the text field. This method salts and hashes the password before storing it in the Password column of my User table.
Question:
How should I validate the password when a user tries to log in?
If I call the CreateSaltedHash() method again it will not match because of the random salt.
Should I be storing the salts in a separate column? Should I be using a delimiter when generating the salted hash? What is the most secure way of validating the input password against the salted and hashed password?
Code: This is what I have so far.
public class PasswordHash
{
public const int SALT_BYTES = 32;
/*
* Method to create a salted hash
*/
public static byte[] CreateSaltedHash(string password)
{
RNGCryptoServiceProvider randromNumberGenerator = new RNGCryptoServiceProvider();
byte[] salt = new byte[SALT_BYTES];
randromNumberGenerator.GetBytes(salt);
HashAlgorithm hashAlgorithm = new SHA256Managed();
byte[] passwordByteArray = Encoding.UTF8.GetBytes(password);
byte[] passwordAndSalt = new byte[passwordByteArray.Length + SALT_BYTES];
for (int i = 0; i < passwordByteArray.Length; i++)
{
passwordAndSalt[i] = passwordByteArray[i];
}
for (int i = 0; i < salt.Length; i++)
{
passwordAndSalt[passwordByteArray.Length + i] = salt[i];
}
return hashAlgorithm.ComputeHash(passwordAndSalt);
}
public static bool OkPassword(string password)
{
//This is where I want to validate the password before logging in.
}
}
Calling the method in the Register class.
User user= new User();
user.password = PasswordHash.CreateSaltedHash(TextBoxUserPassword.Text);
When you first generate the hash, you need to store both the salt and the final hash - then re-use that same salt for future comparisons.
So you'd change your CreateSaltedHash
method to take a password and a salt, and write a new CreateSalt
method to generate the salt when a password is created/changed which is stored alongside the final hash.