Java MD5哈希不匹配.NET哈希

时间:2011-03-23 14:29:14

标签: java hash md5

我有一个用C#编写的web服务来处理一些值的验证。在其中我需要检查在调用Java客户端中生成的MD5哈希。

Java客户端以这种方式生成哈希

Charset utf8Charset = Charset.forName("UTF-8");

byte[] bytesOfPhrase = phrase.getBytes(utf8Charset);
MessageDigest md = MessageDigest.getInstance("MD5");

byte[] thedigest = md.digest(bytesOfPhrase);
this._AuthenticationToken = new String(thedigest, utf8Charset);

C#webservice以这种方式生成它:

private static string HashString(string toHash)
{
    MD5CryptoServiceProvider md5Provider = new MD5CryptoServiceProvider();

    byte[] hashedBytes = md5Provider.ComputeHash(_StringEncoding.GetBytes(toHash));
    return Convert.ToBase64String(hashedBytes);
}

我在Java代码中尝试了几个字符集,但它们都没有产生任何类似于Java生成的字符串的字符串。使用在每次调用期间相同的硬编码值(意味着我已经对参数进行硬编码以使哈希值匹配)仍会产生奇怪的Java字符串。

C#散列值示例:

  

6wM7McddLBjofdFJ3rU6 /克==

我发布了Java产生的字符串示例,但它有一些非常奇怪的字符,我认为我不能在这里粘贴。

我做错了什么?

4 个答案:

答案 0 :(得分:7)

这基本上是已损坏的代码:

// Badly broken
byte[] thedigest = md.digest(bytesOfPhrase);
this._AuthenticationToken = new String(thedigest, utf8Charset);

永远不要尝试通过将任意二进制数据传递给String构造函数来对其进行编码。 始终使用base64,或hex,或类似的东西。 Apache Commons Codec有一个Base64编码器,或者这个public domain version有一个更令人愉快的API。

等效的C#将是:

// Equally broken
byte[] hashedBytes = md5Provider.ComputeHash(Encoding.UTF8.GetBytes(toHash));
return Encoding.UTF8.GetString(hashedBytes);

MD5摘要生成的二进制数据实际有效的UTF-8字节序列的可能性有多大?

另外两件事需要注意:

  • 您可以使用MD5类在.NET中稍微更轻松地获取MD5哈希:

    byte[] hash;
    using (MD5 md5 = MD5.Create())
    {
        hash = md5.ComputeHash(bytes);
    }
    // Use hash
    

    注意事后使用using语句处理实例。我对此的主要偏好是,它比MD5更容易记住,阅读和输入MD5CryptoServiceProvider:)

  • 您尚未明确_StringEncoding是什么,但代码应该只使用Encoding.UTF8来匹配Java。

答案 1 :(得分:3)

您的C#摘要位于Base64中,但您的Java摘要不是。将thedigest转换为Base64。

答案 2 :(得分:0)

在C#中,您使用Base64对字节进行编码。在Java中,您将字节解释为UTF-8字符串。

答案 3 :(得分:0)

您的C#代码将MD5哈希输出为BASE64编码,但java代码不会。 比较两个MD5哈希值的通用方法是比较其十六进制表示(16bytes - > 32digits)。