在C中返回错误的MD5哈希

Pig*_*aax 6 c string hash md5

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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
Run Code Online (Sandbox Code Playgroud)

oua*_*uah 5

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

要将其固定在您身边,请替换:

const char *s = "Hello World";
Run Code Online (Sandbox Code Playgroud)

经过

const char s[64] = "Hello World";
Run Code Online (Sandbox Code Playgroud)

编辑

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

typedef unsigned long int UINT4;
Run Code Online (Sandbox Code Playgroud)

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

typedef unsigned int UINT4;
Run Code Online (Sandbox Code Playgroud)

  • 或者你可以使用 `stdint.h` 中的可移植类型,`uint32_t` 总是四个字节。 (2认同)

vip*_*ipw 1

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

\n\n

填充的格式称为Merkle\xe2\x80\x93Damg\xc3\xa5rd 结构

\n\n

您可以在此处找到一些包含填充的伪代码。

\n

  • 难道“MD5Finalize()”不应该执行所有必要的填充吗? (4认同)