在C中返回错误的MD5哈希

我正在尝试使用原始/未触摸的md5.h和来自http://www.arp.harvard.edu的 md5c.c为字符串“Hello World”生成MD5哈希。 但我的结果与我测试的所有md5在线工具不同。 这个代码怎么了? 谢谢。

#include  #include  #include  #include "md5.h" void MD5hash(unsigned char *data, unsigned int dataLen, unsigned char *digest) { MD5_CTX c; MD5Init(&c); MD5Update(&c, data, dataLen); MD5Final(digest, &c); } int main(int argc, const char * argv[]) { unsigned char digest[16]; const char *s = "Hello World"; unsigned int l = (unsigned int)strlen(s); MD5hash((unsigned char *)s, l, digest); for(int i = 0; i < 16; ++i) printf("%02x", digest[i]); return 0; } // My result: f2877a72c40494318c4b050bb436c582 // But online tools output: b10a8db164e0754105b7a99be72e3fe5 

您有填充问题。 MD5哈希算法适用于512位块。 当最后一个块少于512位时,需要填充它。 在您的示例中,第一个块也是最后一个块,因为它小于512位。

填充格式称为Merkle-Damgård结构 。

你可以在这里找到一些包含填充的伪代码。

正如@vipw所提到的那样,填充存在问题。 此MD5实现无法正确管理不是MD5块大小(512位/ 64字节)倍数的消息大小的填充。

要将它固定在您身边,请更换:

 const char *s = "Hello World"; 

通过

 const char s[64] = "Hello World"; 

编辑

在MD5实现中存在与可移植性相关的第二个问题。 在md5.h有这种类型的别名:

 typedef unsigned long int UINT4; 

在Linux x86_64系统(您正在使用)上,必须将其更改为:

 typedef unsigned int UINT4;