Here\'s the deal: I\'m moving a .NET website to Python. I have a database with passwords hashed using the System.Security.Cryptography.SHA1Managed utility.
I\'m cre
Thanks Gareth Stephenson! your answer had all the answers I needed. I was getting completely lost with this. I needed to upgrade a legacy module that was using this enterprise library, but there were so many problems with compiling I couldn't debug the code. Keeping the code opened a zillion other problems with dependencies and public key token mismatches / versions. So I re-wrote the functions needed based on Gareth's answer. I eventually found the encryption used in the config file. This can be in the app.config (in my case), web.config or other config somewhere:
The code I wrote is:
//Because of the random salt added, each time you hash a password it will create a new result.
public static string GetHashedValue(string password)
{
//this will create a new hash?
//Hashed Password Formula: Base64(salt + Sha1(salt + value))
var crypto = new SHA1CryptoServiceProvider();
byte[] saltBytes = new byte[16];
RandomNumberGenerator.Create().GetBytes(saltBytes);
byte[] checkPasswordBytes = Encoding.Unicode.GetBytes(password);
byte[] tempResult = crypto.ComputeHash(saltBytes.Concat(checkPasswordBytes).ToArray()); //ComputeHash(salt + value)
byte[] resultBytes = saltBytes.Concat(tempResult).ToArray(); //salt + ComputeHash(salt + value)
return Convert.ToBase64String(resultBytes);
}
and to check the validity of a password:
public static bool IsPasswordValid(string passwordToCheck, string savedPassword)
{
bool retVal = false;
var crypto = new SHA1CryptoServiceProvider();
//get the salt, which is part of the saved password. These are the first 16 bytes.
byte[] storedPasswordBytes = Convert.FromBase64String(savedPassword);
byte[] saltBytes = new byte[16];
Array.Copy(storedPasswordBytes, saltBytes, 16);
//hash the password that you want to check with the same salt and the same algoritm:
byte[] checkPasswordBytes = Encoding.Unicode.GetBytes(passwordToCheck);
byte[] tempResult = crypto.ComputeHash(saltBytes.Concat(checkPasswordBytes).ToArray()); //ComputeHash(salt + value)
byte[] resultBytes = saltBytes.Concat(tempResult).ToArray(); //salt + ComputeHash(salt + value)
string resultString = Convert.ToBase64String(resultBytes);
if (savedPassword == resultString)
{
retVal = true;
}
return retVal;
}
And that just before I thought I would have to reset all my customers' passwords... I hope this will safe someone else as well one day!