Tuesday, 4 January 2011

Hash Password using HMACSHA1 or HMACSHA512

Quite a handy snippet to generate an HMACSHA1 encoded string, I use this for passwords, but it could be used generate a check sum when passing values through to a webservice.

public static string GeneratePassword(string valueToHash)
{
byte[] saltValueBytes = Encoding.ASCII.GetBytes("This is for the Salt");
// Change passkey value to known value, I tend to use a guid
Rfc2898DeriveBytes passwordKey = new Rfc2898DeriveBytes("96D9E8D3-1318-4291-B459-84EAB0E268A6", saltValueBytes);
byte[] secretKey = passwordKey.GetBytes(16);
HMACSHA1 myHash = new HMACSHA1(secretKey);
byte[] encodedValue = Encoding.UTF8.GetBytes(valueToHash);

return Convert.ToBase64String(myHash.ComputeHash(encodedValue));
}


The problem with this, has always been everyone has the same salt.

So a change in security and use of SHA512:

With a way to generate a unique Salt:


public byte[] GenerateSalt()
        {
            System.Security.Cryptography.RNGCryptoServiceProvider r = new System.Security.Cryptography.RNGCryptoServiceProvider();

            byte[] array = new byte[16];

            r.GetBytes(array);

            return array;
        }

And return the Hash value with Generated Salt Passed in:

        public string GetHash(string password, byte[] salt)
        {
            string ret = string.Empty;

            try
            {
                byte[] passwordBytes = Encoding.ASCII.GetBytes(password);

                byte[] input = new byte[salt.Length + passwordBytes.Length];

                salt.CopyTo(input, 0);

                passwordBytes.CopyTo(input, salt.Length);

                System.Security.Cryptography.SHA512CryptoServiceProvider cr = new System.Security.Cryptography.SHA512CryptoServiceProvider();

                ret = Convert.ToBase64String(cr.ComputeHash(input));
            }
            catch (Exception Ex)
            {
                throw new Exception("Error hashing password", Ex);
            }

            return ret;
        }

Remember to save the salt somewhere that can be referrenced with the encrypted value, so you can check it.

No comments:

Post a Comment