Returning wrong MD5 hash in C

2019-06-19 13:06发布

I am trying to generate MD5 hash for an string "Hello World" using the original/untouched md5.h and md5c.c from http://www.arp.harvard.edu. But my result differs from all md5 online tools i have tested. Whats wrong this this code? Thank you.

#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

标签: c string hash md5
2条回答
虎瘦雄心在
2楼-- · 2019-06-19 13:18

As @vipw mentioned there is an issue with padding. This MD5 implementation does not correctly manage padding for message sizes that are not a multiple of a MD5 block size (512-bit / 64 bytes).

To fix it on your side, replace:

const char *s = "Hello World";

by

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

EDIT:

There was a second issue related to portability in this MD5 implementation. In md5.h there is this type alias:

typedef unsigned long int UINT4;

On a Linux x86_64 system (which you are using), this must be changed to this:

typedef unsigned int UINT4;
查看更多
三岁会撩人
3楼-- · 2019-06-19 13:21

You have an issue with padding. The MD5 Hash algorithm works on 512-bit blocks. When your final block is less than 512 bits, it needs to be padded. In your example, the first block is also the last block because it's less than 512 bits.

The padding is format is called Merkle–Damgård construction.

You can find some pseudo code that includes padding here.

查看更多
登录 后发表回答