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
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:
by
EDIT:
There was a second issue related to portability in this MD5 implementation. In
md5.h
there is this type alias:On a Linux x86_64 system (which you are using), this must be changed to this:
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.