I'm trying to sign up users through a PHP webapp and validate them with C# under .net core 7. I'm having difficulty getting the hashes to match between the front and back ends. I encode the password hash in PHP like this:
$salt = bin2hex(random_bytes(64));
$binPassword = hash_pbkdf2("sha512", "test", $salt, 1000, 64,true);
$hashedPassword = bin2hex($binPassword);
Then $salt and $hashedPassword go into a database which I retrieve from my C# backend. Then
byte[] saltBytes = hex2bin(salt);
var pbkdf2 = new Rfc2898DeriveBytes(
"test",
saltBytes,
1000,
HashAlgorithmName.SHA512);
var hashBytes = pbkdf2.GetBytes(64);
var myHash = bin2hex(hashBytes);
Console.WriteLine($"myHash={myHash}");
Console.WriteLine($"hashedPassword={hashedPassword}");
The bin2hex() and hex2bin() routines in C# are as follows:
static string bin2hex(byte[] bytes)
{
var sb = new StringBuilder();
foreach (byte b in bytes)
{
var hex = b.ToString("x2");
sb.Append(hex);
}
return sb.ToString();
}
static byte[] hex2bin(string hexdata)
{
if (hexdata == null)
throw new ArgumentNullException("hexdata");
if (hexdata.Length % 2 != 0)
throw new ArgumentException("hexdata should have even length");
byte[] bytes = new byte[hexdata.Length / 2];
for (int i = 0; i < hexdata.Length; i += 2)
bytes[i / 2] = (byte) (HexValue(hexdata[i]) * 0x10
+ HexValue(hexdata[i + 1]));
return bytes;
}
static int HexValue(char c)
{
int ch = (int) c;
if (ch >= (int) '0' && ch <= (int) '9')
return ch - (int) '0';
if (ch >= (int) 'a' && ch <= (int) 'f')
return ch - (int) 'a' + 10;
if (ch >= (int) 'A' && ch <= (int) 'F')
return ch - (int) 'A' + 10;
throw new ArgumentException("Not a hexadecimal digit.");
}
Im expecting the hashes to match. My latest run of the backend produces this:
myHash=ef3860d356217f9c69d6aea4647ef58bd6dc64ca2559699ca56721b606188508456f3939634f78ffb63a0b79c1e696985705ff5e972e13c8def535a732e73cbf
hashedPassword=7a2dcfb5217198d8b07dd6ded7cf02b1bb7e4c1017a52f2c611b28a053c1d46c5db4f9355e05f5212984adf33465e0e3d7c11ecb2385f47a26e87c30b0a9ba99
The hashes don't match.