Microsoft SHA256散列对空字符串的值给出了“不正确”的结果。

huangapple go评论68阅读模式
英文:

Microsoft SHA256 Hash Gives "Incorrect" value for string.empty

问题

差异的原因在于编码方式的不同。在你提到的情况中:

  • 如果使用SHA256哈希算法对空字符串进行哈希,并将其以十六进制字符串形式表示,结果是 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"。
  • 如果使用SHA256哈希算法对空字符串进行哈希,并将其以Base64编码的形式表示,结果是 "ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3ODUyYjg1NQ=="。

然而,你提到的C#代码中使用的是UTF-8编码的空字符串进行SHA256哈希,并将结果以Base64编码的形式表示,因此结果是 "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="。

差异的原因是编码方式的不同,一个是对十六进制字符串进行哈希,另一个是对UTF-8编码的字符串进行哈希,然后再进行Base64编码。

英文:

I don't know if it's a "spec" or generally agreed upon or linux or just google, but many sites say that the SHA256 hash for an empty string is e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 or base64
"ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3ODUyYjg1NQ=="

However, given the following code in C#

    using (var sha256 = SHA256.Create())
    {
        var contentBytes = System.Text.Encoding.UTF8.GetBytes(content);
        byte[] hashedBytes = sha256.ComputeHash(contentBytes);
        var hash = Convert.ToBase64String(hashedBytes);
        return hash;
    }

the base64 value of hash where content=string.empty or content="" will be "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="

Why the difference?

答案1

得分: 1

You're most likely seeing a BOM being emitted from the UTF8 encoder.

Edit: Maybe not. This works for me:

var content = string.Empty;
using (var sha256 = SHA256.Create())
{
    var contentBytes = System.Text.Encoding.UTF8.GetBytes(content);
    byte[] hashedBytes = sha256.ComputeHash(contentBytes);
    Console.WriteLine(BitConverter.ToString(hashedBytes).Replace("-", "").ToLowerInvariant());
}

Output:

e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

The "ZTNiMG..." is the Base64 representation of the string "e3b0c..." and not the bytes e3 b0 c4.... So the "47DEQ..." is actually correct.

If you insist on the "ZTNiMG..." string then use this:

var content = string.Empty;
using (var sha256 = SHA256.Create())
{
    var contentBytes = System.Text.Encoding.UTF8.GetBytes(content);
    byte[] hashedBytes = sha256.ComputeHash(contentBytes);
    Console.WriteLine(Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(BitConverter.ToString(hashedBytes).Replace("-", "").ToLowerInvariant())));
}

Output:
ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3ODUyYjg1NQ==

英文:

<s>You're most likely seeing a BOM being emitted from the UTF8 encoder.</s>

Edit: Maybe not. This works for me:

var content = string.Empty;
using (var sha256 = SHA256.Create())
{
	var contentBytes = System.Text.Encoding.UTF8.GetBytes(content);
	byte[] hashedBytes = sha256.ComputeHash(contentBytes);
	Console.WriteLine(BitConverter.ToString(hashedBytes).Replace(&quot;-&quot;,&quot;&quot;).ToLowerInvariant());
}

Output:

e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

The "ZTNiMG..." is the Base64 representation of the string "e3b0c..." and not the bytes e3 b0 c4.... So the "47DEQ..." is actually correct.

If you insist on the "ZTNiMG..." string then use this:

var content = string.Empty;
using (var sha256 = SHA256.Create())
{
	var contentBytes = System.Text.Encoding.UTF8.GetBytes(content);
	byte[] hashedBytes = sha256.ComputeHash(contentBytes);
	Console.WriteLine(Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(BitConverter.ToString(hashedBytes).Replace(&quot;-&quot;,&quot;&quot;).ToLowerInvariant())));
}

Output:
ZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3ODUyYjg1NQ==

huangapple
  • 本文由 发表于 2023年5月18日 08:40:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/76277038.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定