Why isn't my PHP SHA256 hash equivalent to C# SHA256Managed hash
为什么这些不一样?
PHP:
1 | $hash = hash('sha256', $userData['salt'] . hash('sha256', $password) ); |
C.*
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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编码字符串,而php正在输出十六进制数。更好的比较方法是将参数true传递到php和base64的哈希函数的末尾,结果是:
1 2 3 | $hash = base64_encode( hash('sha256', $userData['salt'] . hash('sha256', $password), true ) ); |
因为它们是不同的。您的C代码在末尾用base64编码对计算出的哈希进行编码。php只返回十六进制数字的字符串。
第一嫌疑犯:
1 | Encoding.UTF8.GetBytes(plainText); |
C使用UTF-8,您的PHP可能不使用,但如果您严格使用US-ASCII子集中的字母,您可能会很幸运。
第二嫌疑犯:
1 | Convert.ToBase64String(tHashBytes); |
在PHP中没有关于base64的内容。
因为PHP会给您一个十六进制编码的结果,所以您也应该在C中切换到十六进制。有关解决方案,请参阅此答案。
嗯,我不是C程序员,但有一件事让我大吃一惊:
1 2 | // Convert result into a base64-encoded string. string hashValue = Convert.ToBase64String(tHashBytes); |
您是否使用C对最终输出进行base64编码?因为你不在PHP中…
1 2 3 4 5 6 7 | 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)); |
写得像顶级代码,它们是一样的