在Java和C上重现相同HMAC MD5的问题

时间:2012-01-07 21:54:34

标签: java c character-encoding md5 hmac

我目前难以重新创建由C上的Java程序生成的HMAC MD5哈希值。非常感谢任何帮助,建议,更正和推荐。 Java程序使用UTF16LE和MAC创建HMAC MD5字符串(编码为长度为32个字符的基本16 HEX字符串);我需要的是在C程序上重新创建相同的结果。

我正在使用MDA的RSA源代码,而HMAC-MD5代码来自RFC 2104(http://www.koders.com/c/fidBA892645B9DFAD21A2B5ED526824968A1204C781.aspx)

我通过用0填充每个偶数字节,在C实现上“模拟”了UTF16LE。当我这样做时,Hex / Int表示似乎在两端都是一致的;但这是正确的方法吗?我认为这是最好的方法,因为HMAC-MD5函数调用只允许一个字节数组(在RFC2104实现中没有双字节数组调用,但这是无关紧要的。)

当我将字符串运行到​​HMAC时 - 你自然会得到“垃圾”。现在我的问题是甚至“垃圾”在整个系统中都不一致(不包括可能基本16编码可能不一致的事实)。我的意思是“ ԙ ”,可能是Java HMAC-MD5的结果,但C可能会给出“v ? ! { ”(仅举个例子) ,而不是实际数据。)

我有两件事我想证实:

  1. 用0填充HMAC-MD5算法填充每个偶数字节? (要么是因为它会在第一个字节之后立即遇到一个空或其他什么)
  2. 我看到不同的“垃圾”是因为C和Java使用不同的字符编码? (运行Ubuntu的同一台机器)
  3. 我将阅读HMAC-MD5和MD5代码以了解它们如何处理进入的字节数组(null偶数字节是否导致问题)。我也很难在C端编写一个正确的编码函数,将结果字符串转换为32个字符的十六进制字符串。任何输入/帮助将不胜感激。

    更新(2月3日):传递有符号/无符号字节数组会改变HMAC-MD5的输出吗? Java实现采用一个字节数组(SIGNED);但C实现采用UNSIGNED字节数组。我认为这也可能是产生不同结果的一个因素。如果这确实影响最终输出;我能做什么?我会在C中传递一个SIGNED字节数组(该方法采用无符号字节数组)还是将SIGNED字节数组转换为无符号?

    谢谢! 克莱门特

2 个答案:

答案 0 :(得分:0)

问题可能是由于你天真地创建了UTF-16字符串。任何大于0x7F(see unicode explanation)的字符都需要扩展为UTF编码方案。

我会首先在C和Java实现之间获取相同的字节字符串,因为这可能是你的问题所在 - 所以我同意你的假设(1)

您是否尝试在不填充C字符串的情况下计算MD5,而只是将其转换为UTF - 您可以使用iconv进行编码实验。

答案 1 :(得分:0)

问题是我使用了RSA实现。在我切换到OpenSSL后,我的所有问题都得到了解决。 RSA实施没有考虑跨平台支持的所有必要细节(包括32位/ 64位处理器)。

始终使用OpenSSL,因为他们已经解决了所有跨平台问题。