Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning wrong MD5 hash in C

Tags:

c

string

hash

md5

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
like image 819
Pigaax Avatar asked Apr 08 '13 09:04

Pigaax


People also ask

Can MD5 hash be changed?

The MD5 hash will change if there's any change to whatever data you input to the MD5 hashing function. If you fed it the permissions and the permission change, then the MD5 hash will change. If you fed it only the contents, then the MD5 hash will change only if the contents change.

What causes MD5 hash to change?

md5sum is used to verify the integrity of files, as virtually any change to a file will cause its MD5 hash to change. Most commonly, md5sum is used to verify that a file has not changed as a result of a faulty file transfer, a disk error or non-malicious meddling.

Can you reverse md5sum?

MD5 is a cryptographic hashing function, which by definition means that it is only computed in one direction and it is not possible to "reverse" it back to its original form.

How do you match MD5?

Type the following command: md5sum [type file name with extension here] [path of the file] -- NOTE: You can also drag the file to the terminal window instead of typing the full path. Hit the Enter key. You'll see the MD5 sum of the file. Match it against the original value.


2 Answers

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;
like image 97
ouah Avatar answered Oct 08 '22 13:10

ouah


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.

like image 38
vipw Avatar answered Oct 08 '22 15:10

vipw