Java MD5 哈希与 .NET 哈希不匹配
我有一个用 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# Web 服务以这种方式生成它的哈希值:
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/g==
我会发布 Java 生成的字符串的示例,但它有一些非常奇怪的字符,我认为我无法粘贴到这里。
我做错了什么?
I have a webservice that is written in C# handling some validation of values. In it I need to check a MD5 hash generated in the calling Java client.
The Java client generates the hash in this manner
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);
The C# webservice generates its has in this manner:
private static string HashString(string toHash)
{
MD5CryptoServiceProvider md5Provider = new MD5CryptoServiceProvider();
byte[] hashedBytes = md5Provider.ComputeHash(_StringEncoding.GetBytes(toHash));
return Convert.ToBase64String(hashedBytes);
}
I've tried several charsets in the Java code, but none of them produce a string that is anywhere similar to the Java produced string. Using hard coded values that are the same during every call (meaning that I've hardcoded the parameters so the hashes should match) still produces an odd Java string.
C# Example of hashed values:
6wM7McddLBjofdFJ3rU6/g==
I'd post the example of the string Java produces, but it has some very odd characters that I do not think I can paste in here.
What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
从根本上来说,这是一个损坏的代码:
永远、永远、永远不会尝试通过将任意二进制数据传递给 String 构造函数来对其进行编码。 始终使用base64、十六进制或类似的东西。 Apache Commons Codec 有一个 Base64 编码器,或者这个 公共域版本有一个稍微更令人愉快的API。
等效的 C# 是:
MD5 摘要生成的二进制数据实际上是有效的 UTF-8 字节序列的可能性有多大?
另外两件事需要注意:
您可以使用
MD5
类在 .NET 中更简单地获取 MD5 哈希值:请注意随后使用
using
语句来处理实例。我对此的主要偏好是它比MD5CryptoServiceProvider
更容易记住、阅读和输入MD5
:)您还没有弄清楚
_StringEncoding< /code> 是,但代码实际上应该只使用
Encoding.UTF8
来匹配 Java。This is fundamentally broken code:
Never, ever, ever try to encode arbitrary binary data by passing it to the String constructor. Always use base64, or hex, or something like that. Apache Commons Codec has a Base64 encoder, or this public domain version has a slightly more pleasant API.
The equivalent C# would be:
What are the chances that the binary data produced by an MD5 digest is actually a valid UTF-8 byte sequence?
Two other things to note:
You can get hold of an MD5 hash slightly more simply in .NET using the
MD5
class:Note the use of the
using
statement to dispose of the instance afterwards. My main preference for this is that it's easier to remember, read and typeMD5
thanMD5CryptoServiceProvider
:)You haven't made it clear what
_StringEncoding
is, but the code should really just useEncoding.UTF8
to match the Java.您的 C# 摘要采用 Base64,但您的 Java 摘要不是。将
thedigest
也转换为 Base64。Your C# digest is in Base64, but your Java digest is not. Convert
thedigest
to Base64 as well.在 C# 中,您使用 Base64 对字节进行编码。在 Java 中,您将字节解释为 UTF-8 字符串。
In C#, you encode the bytes using Base64. In Java, you interpret the bytes as a UTF-8-string.
您的 C# 代码将 MD5 哈希输出为 BASE64 编码,但 Java 代码不会。
比较两个 MD5 哈希值的通用方法是比较其十六进制表示形式(16 字节 -> 32 位数字)。
Your C# code outputs MD5 hash as BASE64-encoded, but java code does not.
A generic method to compare two MD5 hashes is to compare its hexadecimal presentation (16bytes -> 32digits).