【问题标题】:Java MD5 hashing not matching C# MD5 hashingJava MD5 散列与 C# MD5 散列不匹配
【发布时间】:2012-06-17 19:57:53
【问题描述】:

我对加密/散列知之甚少。

我必须散列一个加密密钥。 Java中的例子是这样的……

String encryptionKey = "test";

    MessageDigest messageDigest = MessageDigest.getInstance("MD5");
    messageDigest.update(encryptionKey.getBytes("UTF-8"), 0, encryptionKey.length());
    byte[] encryptionKeyBytes = messageDigest.digest();

如果我错了,现在纠正我,但上面的代码使用 MD5 算法对字符串进行哈希处理。

当我在 C# 中散列相同的字符串时,我想要相同的结果。

我当前的 C# 代码如下所示...

string encryptionKey = "test";

        var md5 = MD5.Create();
        var keyBytes = Encoding.UTF8.GetBytes(encryptionKey);
        byte[] encryptionKeyBytes = md5.ComputeHash(keyBytes);

但是结束字节结果不匹配。

Java 得到...

[0] 9   
[1] -113    
[2] 107 
[3] -51 
[4] 70  
[5] 33  
[6] -45 
[7] 115 
[8] -54 
[9] -34 
[10]    78  
[11]    -125    
[12]    38  
[13]    39  
[14]    -76 
[15]    -10 

C# 得到...

    [0] 9   byte
    [1] 143 byte
    [2] 107 byte
    [3] 205 byte
    [4] 70  byte
    [5] 33  byte
    [6] 211 byte
    [7] 115 byte
    [8] 202 byte
    [9] 222 byte
    [10]    78  byte
    [11]    131 byte
    [12]    38  byte
    [13]    39  byte
    [14]    180 byte
    [15]    246 byte

我需要我的 C# 代码来获得与 Java 代码相同的结果(而不是相反),有什么想法吗?

谢谢。

【问题讨论】:

  • Java 的字节是有符号的。 C# 字节不是。请注意,只有 Java 字节为负的地方是错误的。
  • 除了相同的结果之外,您在 java 代码中还有一个非常严重的错误:encryptionKey.getBytes("UTF-8"), 0, encryptionKey.length() 我让您自己弄清楚错误是什么。最后比较直接字符串表示(toString)总是一个坏主意
  • @bestsss 我正在使用断点来检查值。我认为断点值是从 toString 表示产生的(可能是错误的)。您将如何比较字节值?
  • 无符号十六进制通常是呈现 byte[] 的标准,因为您可以很容易地看到两个半字节。顺便说一句,您发现错误在哪里了吗?
  • @bestsss 它使用 byte[] 数组作为数据,长度来自字符串(而不是 byte[])。那是你指出的吗?如果没有,我不知道。该 java 代码是发送给我的加密/解密演示。我必须编写的 C# 才能产生相同的结果。

标签: c# java md5 hash message-digest


【解决方案1】:

实际上,结果相同的。与其他整数类型一样,字节值可以解释为有符号或无符号。例如,10001111 将对应于 143(您的第二个 C# 值)如果解释为无符号。但是,如果解释为 signed(使用 two’s complement),则其值为 -113(您的第二个 Java 值)。

因此,差异似乎是由于您的值在 Java 中被格式化为签名但在 C# 中未签名。如果你想在 C# 中获取有符号字节,你可以使用:

sbyte[] encryptionKeyBytesSigned = 
    encryptionKeyBytes.Select(b => (sbyte)b).ToArray();

但是,请注意,这不仅仅是仅在显示值时出现的格式问题。保存到文件时,两个结果应该相同。

【讨论】:

  • 感谢您的回答...如果我阅读正确,最后的陈述似乎与此相矛盾。如果您将两者都保存到文件并且它们是相同的,那么它只是显示值时出现的格式问题。你能澄清一下吗?我将采用这个散列值(以字节 [] 为单位)并将其用作加密密钥。因此,如果这只是一个显示问题,我认为没有转换就可以了。我认为加密函数不会使用 sbyte[] 而不是 byte[]。
  • N/m。你只是警告我检查并确定。我明白了。
  • @Theo:是的,我认为这是一个格式问题,当保存到文件时,即使没有将 C# 值转换为有符号字节,生成的文件也应该是相同的。不过,老实说,我对 Java 不是很熟悉(我只能保证你的 C# 代码),所以我会进行一些测试以确保。
  • 您对格式问题的看法是正确的。写入文件时,两者都显示相同的乱码。感谢您的帮助。
猜你喜欢
  • 2013-08-29
  • 1970-01-01
  • 2014-11-18
  • 2011-06-08
  • 1970-01-01
  • 1970-01-01
  • 2016-09-19
  • 2015-06-25
  • 1970-01-01
相关资源
最近更新 更多