PBKDF2 interoperability: PHP and C#

63 Views Asked by At

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.

0

There are 0 best solutions below