为什么不是';t我的PHP SHA256哈希相当于C#SHA256托管哈希


Why isn't my PHP SHA256 hash equivalent to C# SHA256Managed hash

为什么这些不一样?

php:

    $hash = hash('sha256', $userData['salt'] . hash('sha256', $password) );

c#

    public static string ComputeHash(string plainText, string salt)
    {
        // Convert plain text into a byte array.
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
        byte[] saltBytes = Encoding.UTF8.GetBytes(salt);
        SHA256Managed hash = new SHA256Managed();
        // Compute hash value of salt.
        byte[] plainHash = hash.ComputeHash(plainTextBytes);
        byte[] concat = new byte[plainHash.Length + saltBytes.Length];
        System.Buffer.BlockCopy(saltBytes, 0, concat, 0, saltBytes.Length);
        System.Buffer.BlockCopy(plainHash, 0, concat, saltBytes.Length, plainHash.Length);
        byte[] tHashBytes = hash.ComputeHash(concat);
        // Convert result into a base64-encoded string.
        string hashValue = Convert.ToBase64String(tHashBytes);
        // Return the result.
        return hashValue;
    }

C#输出一个base64 ecoded字符串,PHP输出一个十六进制数字。一个更好的比较可能是将参数true传递到PHP和base64的哈希函数的末尾,结果是:

 $hash = base64_encode(
           hash('sha256', $userData['salt'] . hash('sha256', $password), true )
         );

因为它们不同。您的C#代码在末尾以Base64编码对计算出的哈希进行编码。PHP只返回一个十六进制数字字符串。

第一个嫌疑人:

Encoding.UTF8.GetBytes(plainText);

C#使用UTF-8,你的PHP可能不会,但如果你严格使用US-ASCII子集中的字母,那就太幸运了。

第二名嫌疑人:

Convert.ToBase64String(tHashBytes);

PHP中没有Base64。

由于PHP会给你一个十六进制编码的结果,你也应该在C#中切换到十六进制。有关解决方案,请参阅此答案。

我不是C#程序员,但有一件事让我大吃一惊:

// Convert result into a base64-encoded string.
string hashValue = Convert.ToBase64String(tHashBytes);

您是否使用C#对最终输出进行base64编码?因为你不是PHP。。。

C#
string toHash = "abcdefg";
SHA256Managed hash = new SHA256Managed();
byte[] signatureData = hash.ComputeHash(new UnicodeEncoding().GetBytes(toHash));
string hashResult = System.Convert.ToBase64String(signatureData);
PHP
print base64_encode(hash("sha256",mb_convert_encoding("abcdefg","UTF-16LE"),true));

像顶级代码一样编写,它们是相同的

C#

string toHash = "abcdefg"; 
SHA256Managed hash = new SHA256Managed(); 
byte[] signatureData = hash.ComputeHash(new UnicodeEncoding().GetBytes(toHash)); 
string hashResult = System.Convert.ToBase64String(signatureData); 

PHP

print base64_encode(hash("sha256",mb_convert_encoding("abcdefg","UTF-16LE"),true));

适用于我。