字符串的MD5哈希

29

需要从字符串获取MD5哈希值。
出现错误,显示MD5为null。
我尝试从一个字符串获取32个字符的MD5哈希值。

using (System.Security.Cryptography.MD5 md5 = 
       System.Security.Cryptography.MD5.Create("TextToHash"))
{
    byte[] retVal = md5.Hash;
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < retVal.Length; i++)
    {
        sb.Append(retVal[i].ToString("x2"));
    }
}
3个回答

55

需要从字符串获取MD5哈希值。

首先,您需要将字符串以某种形式转换为二进制数据。如何进行取决于您的要求,但可能是某种编码的 Encoding.GetBytes……不过您需要确定使用哪种编码。例如,这个哈希值是否需要与其他地方创建的哈希值匹配?

出现错误,MD5为空。

那是因为您错误地使用了 MD5.Create。参数应该是一个“算法名称”。您几乎肯定应该使用 parameterless overload

我猜您想要的是:

byte[] hash;
using (MD5 md5 = MD5.Create())
{
    hash = md5.ComputeHash(Encoding.UTF8.GetBytes(text));
}
// Now convert the binary hash into text if you must...

1
如果数据来自于 SQL varchar(max),那么使用UTF8是最好的选择吗? - paparazzo
关于无参数重载 - 是否存在默认算法在一个 .Net 版本到另一个版本会发生变化的风险?如果是这样,那么同一字符串的哈希值在不同版本之间将不匹配? - xanadont
2
@xanadont:不会。MD5是一种标准化算法。结果改变基本上就是一个错误。 - Jon Skeet
太好了。谢谢@JonSkeet - xanadont

28

传递给Create的字符串不是“要进行哈希处理的文本”,而是要使用的哈希算法。我猜想您想要:

using (System.Security.Cryptography.MD5 md5 = 
   System.Security.Cryptography.MD5.Create())
{
    byte[] retVal = md5.ComputeHash(Encoding.Unicode.GetBytes("TextToHash"));
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < retVal.Length; i++)
    {
        sb.Append(retVal[i].ToString("x2"));
    }
}

1
嗨,里德:我有一个问题:我该使用哪种编码方式?在我的情况下,我需要计算一个作为查询字符串接收到的哈希值。(因此,在它被发布到http时,它可能是UTF-8),但是,一旦它被存储在.Net字符串中,它现在会是Unicode(UTF-16)吗,因为那是本地编码方式?这个转换是自动完成的吗? - JMarsch
@JMarsch 是的 - 如果您使用 Encoding.Unicode,它很可能会“正常工作”,如果它最初是 UTF-8。 - Reed Copsey
请注意,如果您的“源”MD5是在字符串的utf-8表示形式上计算出来的,那么如果您现在改用utf-16,您将得到不同的MD5。即使您的字符串中只有ASCII字符,这也是正确的。 - brighty
1
使用 Encoding.Unicode 而不是 UTF-8 将导致与大多数 JavaScript 库在客户端上生成的哈希值不同 - 大多数库会转换为 utf8。这并不意味着答案是错误的,但我只是作为一个警告来写这个,如果有人在客户端和服务器上得到不同的 MD5 哈希值 - 字符串的初步编码可能会逃过注意,让某人认为存在错误。 - Ognyan Dimitrov

1
你得到一个null返回的原因是Create方法中的string参数指定了算法,而不是被散列的文本。由于没有TextToHash算法,因此你会得到null作为返回值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接