散列与SHA256字符串(Hashing a string with Sha256)

2019-06-18 04:12发布

我尝试使用SHA256,我使用下面的代码以哈希的字符串:

using System;
using System.Security.Cryptography;
using System.Text;
 public class Hash
    {
    public static string getHashSha256(string text)
    {
        byte[] bytes = Encoding.Unicode.GetBytes(text);
        SHA256Managed hashstring = new SHA256Managed();
        byte[] hash = hashstring.ComputeHash(bytes);
        string hashString = string.Empty;
        foreach (byte x in hash)
        {
            hashString += String.Format("{0:x2}", x);
        }
        return hashString;
    }
}

然而,这个代码给出了比我朋友的PHP显著不同的结果,以及在线发生器(如该发电机 )

有谁知道错误是什么? 不同的基地?

Answer 1:

Encoding.Unicode是微软为UTF-16误导性名称(双宽编码,在Windows世界中使用的历史原因,但不使用其他任何人)。 http://msdn.microsoft.com/en-us/library/system.text.encoding.unicode.aspx

如果您检查您的bytes数组,你会看到每一个第二个字节是0x00 (因为双宽编码)。

您应该使用Encoding.UTF8.GetBytes代替。

但同时,你会看到不同的结果,这取决于你是否不考虑终止'\0'字节是你散列数据的一部分。 散列两个字节"Hi"将给从散列三个字节一个不同的结果"Hi" 。 你必须决定你想做的事情。 (想必你想做哪一个朋友的PHP代码做什么。)

对于ASCII文本, Encoding.UTF8肯定是合适的。 如果你的目标与你的朋友的代码完美兼容,甚至在非ASCII输入,你最好多试几个测试用例非ASCII字符,如é ,看看你的结果是否仍然匹配。 如果没有,你必须搞清楚你的​​朋友真的是用什么编码; 它可能是使用Unicode的发明之前是受欢迎的8位“代码页”中的一个。 (同样,我认为Windows是最主要的原因,还有人需要担心“代码页”。)



Answer 2:

我也有这个问题,实现另一种风格,但我忘了,我得到了它,因为它是2年前。

static string sha256(string randomString)
{
    var crypt = new SHA256Managed();
    string hash = String.Empty;
    byte[] crypto = crypt.ComputeHash(Encoding.ASCII.GetBytes(randomString));
    foreach (byte theByte in crypto)
    {
        hash += theByte.ToString("x2");
    }
    return hash;
}

当我输入类似abcdefghi2013由于某种原因,它给我的登录模块不同的结果,并导致错误。 然后我试图修改代码以同样的方式通过Quuxplusone的建议,改变了编码从ASCIIUTF8那么它终于成功了!

static string sha256(string randomString)
{
    var crypt = new System.Security.Cryptography.SHA256Managed();
    var hash = new System.Text.StringBuilder();
    byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(randomString));
    foreach (byte theByte in crypto)
    {
        hash.Append(theByte.ToString("x2"));
    }
    return hash.ToString();
}

再次感谢Quuxplusone的精彩和详细的解答! :)



Answer 3:

在PHP版本,你可以在最后一个参数发送“真”,但默认为“假”。 ,把“SHA256”作为第一个参数时,下面的算法等同于默认的PHP的散列函数:

public static string GetSha256FromString(string strData)
    {
        var message = Encoding.ASCII.GetBytes(strData);
        SHA256Managed hashString = new SHA256Managed();
        string hex = "";

        var hashValue = hashString.ComputeHash(message);
        foreach (byte x in hashValue)
        {
            hex += String.Format("{0:x2}", x);
        }
        return hex;
    }


文章来源: Hashing a string with Sha256