I am currently trying to upgrade a project of mine from .NET 3.5 to .NET 4.0
Everything was going really well, all code compiled, all tests passed.
Then I hit a problem deploying to my staging environment.
Suddenly my logins were no longer working.
It seems my SHA1 hashed passwords are being hashed differently in .NET 4.
I am using the SHA1CryptoServiceProvider:
SHA1CryptoServiceProvidercryptoTransformSHA1 = new SHA1CryptoServiceProvider();
To test I created a new Visual Studio project with 2 console applications.
The first targeted at .NET Framework 3.5 and the second at 4.0.
I ran exactly the same hashing code in both and different results were produced.
Why is this happening and how can I fix this?
I obviously cannot go update all of my users passwords considering I do not know what they are.
Any help would be greatly appreciated.
CODE SAMPLE
public static class SHA1Hash
{
public static string Hash(string stringToHash)
{
return (Hash(stringToHash, Encoding.Default));
}
public static string Hash(string stringToHash, Encoding enc)
{
byte[] buffer = enc.GetBytes(stringToHash + stringToHash.Reverse());
var cryptoTransformSHA1 = new SHA1CryptoServiceProvider();
string hash = BitConverter.ToString(cryptoTransformSHA1.ComputeHash(buffer));
return hash;
}
}
One of the comments led me onto finding the bug in my code.
When creating my byte array to be hashed, I was trying to append the string with a reversed version of itself.
E.g. given "password" to hash I would actually hash "passworddrowssap"
However my code has a slight bug in it:
byte[] buffer = enc.GetBytes(stringToHash + stringToHash.Reverse());
.Reverse() is a Linq extension method that can reverse a string.
However it doesn't return a string, it returns:
IEnumerable<Char>
Calling .ToString() on this type actually returns:
System.Linq.Enumerable+d__99`1[System.Char]
Doing the same thing in .NET 4.0 returns
System.Linq.Enumerable+d__a0`1[System.Char]
Hence my passwords were being hashed differently.
What I should have done to create by byte array was:
byte[] buffer = enc.GetBytes(stringToHash + new String(stringToHash.Reverse().ToArray()));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With