SHA1CryptoServiceProvider in .NET doesn't match UNIX shasum
I'm trying to share authentication between an ASP.NET app and another UNIX-based app, where the hashed password is stored in the database. I need to ensure the hashing algorithms on both platforms match.
This is how I'm hashing in C#:
var sha1 = new SHA1CryptoServiceProvider(); var passwordBytes = Encoding.UTF8.GetBytes(password); var passwordHash = sha1.ComputeHash(passwordBytes); var base64 = Convert.ToBase64String(passwordHash); return base64;
If I use the password p@ssw0rd
the hash is 57B2AD99044D337197C0C39FD3823568FF81E48A
and the base64 of that hash is V7KtmQRNM3GXwMOf04I1aP+B5Io=
. The base64 hash is what is stored in the db.
If I do the same thing on UNIX, I get a totally different hash:
echo p@ssw0rd | iconv -f ISO-8859-1 -t UTF-8 | shasum -a 1 | base64 -e开发者_如何学JAVA
produces
ZTU3NmQwNmUzMTAwNmRkNzFhNTFjZTg5ZjViMGI4NWM2NTMyNzg3OCAgLQo=
If you try it with OpenSSL, use this echo "p@ssw0rd" | openssl dgst -sha1 | openssl enc -base64
and you will get the same hash.
What is different about the two SHA1 algorithms that causes different hashes to be computed? I'm not salting these either.
UPDATE
The secret sauce is as follows:
echo -n "p@ssw0rd" | openssl dgst -sha1 -binary | openssl enc -base64
echo -n
strips the newline, and -binary
is essential.
Hope this can help someone.
Thanks, Mark
- echo adds a newline, you need to do
echo -n
- shasum might do the same, check the output of that before you pipe it to base64)
- sha1.ComputeHash() gives you back binary hash representation ,not the hexadecimal representation as the shasum utility produces - which means you're base64 encoding different things in C# vs the unix command line. Use e.g.
var passwordHashHex = String.Concat(Array.ConvertAll(passwordHash , x => x.ToString("X2"));
to convert to hex before you do the base64 conversion in C#
According to the manual:
The sums are computed as described in FIPS PUB 180-2. When checking, the input should be a former output of this program. The default mode is to print a line with checksum, a character indicating type ('*' for binary, '?' for portable, ' ' for text), and name for each FILE.
It's probably (I don't know) generating a salted hash. It's not of a length consistent with just a hash value alone.
Have you tried using "sha1sum" instead? I get conflicting information on this one, but it might work.
精彩评论