I have a bunch of old password hashes that were done using PWDENCRYPT in SQL Server. I would now like to validate these hashes in my C# application (which will subsequently be updated if password matches) without sending the actual password to SQL Server. How can this be done?
1 Answer
Following the advice in this answer (https://stackoverflow.com/a/18154134/545430) you can write something like this to check passwords encrypted with PWDENCRYPT on SQL Server 2008.
SqlConnection conn = new SqlConnection(<your connection string>);
conn.Open();
SqlCommand cmd = new SqlCommand(<select hash field>, conn);
SqlDataReader reader = cmd.ExecuteReader();
byte[] pwHash = new byte[20];
byte[] dbHash = new byte[26];
reader.Read();
reader.GetBytes(0, 0, dbHash, 0, 26);
int header = BitConverter.ToChar(dbHash, 0);
if (header == 1) //SHA1 encryption in Server 2008
{
byte[] salt = new byte[4];
Buffer.BlockCopy(dbHash, 2, salt, 0, 4);
Buffer.BlockCopy(dbHash, 6, pwHash, 0, 20);
HashAlgorithm cryptoThing = SHA1.Create();
byte[] test = cryptoThing.ComputeHash(Encoding.Unicode.GetBytes("mypw" + Encoding.Unicode.GetString(salt)));
if (pwHash.SequenceEqual(test))
{
//Password is good
}
}
Passwords done in 2012 or later use the SHA2-256 and have a header value of 2. This code could be easily updated to handle that as well.