質問

I have looked and found code to take a PHP sha512 hash and match it inside C#. I am currently looking for a way to go from a hash that was made in C# and get the same result in PHP. We are slowly moving away from asp.net to PHP and need a way to check our passwords in the database. Here is the C# code used to make the hash.

// Create a hash from a pwd and salt using sha512
    public static string CreatePasswordHash(string _password, string _salt)
    {
        string saltAndPwd = String.Concat(_password, _salt);
        SHA512 sha512 = new System.Security.Cryptography.SHA512Managed();

        byte[] sha512Bytes = System.Text.Encoding.Default.GetBytes(saltAndPwd);

        byte[] cryString = sha512.ComputeHash(sha512Bytes);

        string hashedPwd = string.Empty;

        for (int i = 0; i < cryString.Length; i++)
        {
            hashedPwd += cryString[i].ToString("X");
        }

        return hashedPwd;
    }

In PHP I have tried to get it to match but it is off by just a few bytes it seems.

function CreatePasswordHash($_password, $_salt)
    {            
        $saltAndPwd = $_password . $_salt;            
        $hashedPwd = hash('sha512', $saltAndPwd);      
        return strtoupper($hashedPwd);
    }

When using the above with the same salt and password here is the results I get. The first result is from C#, and the second result is from PHP:

60BB73FDA3FF7A444870C6D0DBC7C6966F8D5AD632B0A02762E0283051D7C54A5F4B01571D1A5BC8C689DBC411FEB92158383A56AFC6AE6074696AF36E16    
60BB73FDA3FF7A444870C6D0DBC7C609066F8D5AD632B0A02762E0283051D7C54A5F4B001571D1A5BC8C689DBC411FEB092158383A56AFC6AE6074696AF36E16

Any ideas on why these are not matching up? Does it have to do with endian byte order?

役に立ちましたか?

解決

try

hashedPwd += cryString[i].ToString("X2");

Editing PHP:

function CreatePasswordHash($_password, $_salt)
{
    $saltAndPwd = $_password . $_salt;
    $hashedPwd = hash('sha512', $saltAndPwd);

    $hex_strs = str_split($hashedPwd,2);

    foreach($hex_strs as &$hex) {
        $hex = preg_replace('/^0/', '', $hex);
    }
    $hashedPwd = implode('', $hex_strs);

    return strtoupper($hashedPwd);
}

他のヒント

The C# print out is not including leading zeros.

Replace

hashedPwd += cryString[i].ToString("X");

with

hashedPwd += cryString[i].ToString("X2");

Double check that you use the same character encoding in C# and PHP. GetBytes returns different results, depending on the encoding. System.Text.Encoding.Default depends on the localization of the OS.

You can try open_ssl_digest

echo openssl_digest($saltAndPwd, 'sha512');

if you have PHP >= 5.3

You could also use the hash_algos function to see which algorithms are supported in your system.

HTH

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top