I have a function to calculate a SHA256 hash with a salt. The salt is then appended onto the hashed password and stored. The function for doing this looks like so:
public static string CalculateHash(string input)
{
var inputBuffer = new List<byte>(Encoding.Unicode.GetBytes(input));
var saltBytes = new byte[16];
using (var rnd = RandomNumberGenerator.Create())
{
rnd.GetBytes(saltBytes);
}
inputBuffer.AddRange(saltBytes);
byte[] hashedBytes;
using (var hasher = new SHA256Managed())
{
hashedBytes = hasher.ComputeHash(inputBuffer.ToArray());
}
var hash = BitConverter.ToString(hashedBytes).Replace("-", string.Empty);
var salt = BitConverter.ToString(saltBytes).Replace("-", string.Empty);
return string.Format("{0}:{1}", hash, salt);
}
It stores a string of 97 characters (including the ':') in length and seems to work well. I am struggling to strip the salt off of the hash when I retrieve it back. The issue I am having is converting the salt, in string form, back to a byte[16]
, which contains the original bytes. I assume once I have these original 16 bytes, I can append them to the user input, and hash the passwords to check for a match.
My current attempt is to split the hashed password and the salt at the colon delimiter and use a GetBytes
function. It works like this:
public static bool ValidatePassword(string password, string hashWithSalt)
{
var split = hashWithSalt.Split(':');
var salt = split[1];
var saltBytes = GetBytes(salt);
}
private static byte[] GetBytes(string str)
{
var bytes = new byte[str.Length * sizeof(char)];
Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
But GetBytes
is currently returning back byte[64]
, which is clearly not the original byte format. How can I go about fixing this?