Reputation: 413
This should be so simple but I've spent 4 hours fiddling with this code and I just can't seem to get it to work.
The PHP code works as follows (I didn't write it and I can't change it, so I'm stuck with it):
$password = hash('sha512', "HelloWorld1");
$salt = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true);
$hashed = hash('sha512', $password.$salt);
$hashed and $salt are stored in the DB as is. That means $salt is already hashed for later on.
I have no idea why they decided to hash everything but what's done is done.
In this case, the result is
Pswd: ab3e648d69a71b33d0420fc3bfc9e2e8e3ef2a300385ea26bc22057a84cd9a5c359bd15c4a0a552122309e58938ce310839cd9d2ecad5f294266015d823331dd
Salt: fb5a0f741db0be2439dc14662aae3fc68eb5e16b446385d3ddd319b862d5e2d4f50488a39487b27fdd8ff7b7b76420fc3ebef2bce9e082ac15c9f2d6fe7d87fc
Now the login code on the C# side just needs to match a plain text hashed password along with the already hashed salt.
string password = "HelloWorld1";
string storedSalt = "fb5a0f741db0be2439dc14662aae3fc68eb5e16b446385d3ddd319b862d5e2d4f50488a39487b27fdd8ff7b7b76420fc3ebef2bce9e082ac15c9f2d6fe7d87fc";
using(SHA512 shaManaged = new SHA512Managed())
{
byte[] hashPassword = shaManaged.ComputeHash(Encoding.UTF8.GetBytes(password));
string hashPasswordString = BitConverter.ToString(hashPassword).Replace("-", "");
byte[] finalHash = shaManaged.ComputeHash(Encoding.UTF8.GetBytes(hashPasswordString + storedSalt));
Debug.WriteLine("Calculated Hash Password: " + BitConverter.ToString(finalHash).Replace("-", ""));
}
Essentially the idea is to
The result is as follows:
Stored Hash Password: AB3E648D69A71B33D0420FC3BFC9E2E8E3EF2A300385EA26BC22057A84CD9A5C359BD15C4A0A552122309E58938CE310839CD9D2ECAD5F294266015D823331DD
Calculated Hash Password: 189ABBA71AAEDDE5C8154558B68D59500A72E64D5F3F3C07EFA94F0126571FBB68C6ADD105E0C029BABF30CADD8A6A6B6E4749075854461A88EE1CE545E84507
Hopefully someone can spot where I'm going wrong :)
Upvotes: 1
Views: 557
Reputation: 509
You have to tweak your code a little bit. Note the ToLowerInvariant()
. C# returns upper case letters as string. As you see in your original code $salt
and $password
are returned with lower case letters, so your self calculated password hash hashPasswordString
must also be lower case before concatenating with your storedSalt
to gain the correct finalHash
. Your shown expected result again uses upper case letters (maybe before stored it was converted in PHP?) so you don't need ToLowerCaseInvariant()
on your final hash string.
Here is the code:
string password = "HelloWorld1";
string storedSalt = "fb5a0f741db0be2439dc14662aae3fc68eb5e16b446385d3ddd319b862d5e2d4f50488a39487b27fdd8ff7b7b76420fc3ebef2bce9e082ac15c9f2d6fe7d87fc";
using (SHA512 shaManaged = new SHA512Managed())
{
byte[] hashPassword = shaManaged.ComputeHash(Encoding.UTF8.GetBytes(password));
string hashPasswordString = BitConverter.ToString(hashPassword).Replace("-", "").ToLowerInvariant(); // Note the ToLowerInvariant();
byte[] finalHash = shaManaged.ComputeHash(Encoding.UTF8.GetBytes(hashPasswordString + storedSalt));
return BitConverter.ToString(finalHash).Replace("-", "");
}
Upvotes: 2