2013-04-08 5 views
6

Ich versuche, MD5-Hash für eine Zeichenfolge "Hallo Welt" mit dem Original/unberührt md5.h und md5c.c von http://www.arp.harvard.edu zu generieren. Aber mein Ergebnis unterscheidet sich von allen MD5-Online-Tools, die ich getestet habe. Was ist das falsch dieser Code? Vielen Dank.MD5-Hash zurücksenden in C

#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 
+0

Als Randnotiz - ich Ihren Code kompiliert haben gegen OpenSSLs MD5 Implementierung - es funktioniert wie erwartet! In der Tat, 'md5.c', die Sie versuchen zu verwenden, kann einfach auf die eine oder andere Weise gebrochen werden. –

Antwort

1

Sie haben ein Problem mit dem Auffüllen. Der MD5-Hash-Algorithmus arbeitet mit 512-Bit-Blöcken. Wenn Ihr letzter Block weniger als 512 Bits hat, muss er gepolstert werden. In Ihrem Beispiel ist der erste Block auch der letzte Block, weil er weniger als 512 Bits hat.

Das Padding-Format heißt Merkle–Damgård construction.

Sie können einen Pseudocode finden, der Padding here enthält.

+4

Ist 'MD5Finalize()' nicht dazu gedacht, alle notwendigen Padding durchzuführen? –

+0

@CodePainters Ja, du hast wahrscheinlich recht. – vipw

+0

@ vipw, du hast Recht. Ich werde es später versuchen (mein Kind weint jetzt zu Hause). Vielen Dank. – Pigaax

3

Wie @vipw erwähnt, gibt es ein Problem mit der Auffüllung. Diese MD5-Implementierung verwaltet das Auffüllen für Nachrichtengrößen nicht, die kein Vielfaches einer MD5-Blockgröße (512 Bit/64 Byte) sind.

Um es zu beheben auf Ihrer Seite, ersetzen:

const char *s = "Hello World"; 

von

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

EDIT:

Es gibt eine zweite Ausgabe war in dieser MD5 Implementierung in Bezug auf Portabilität. In md5.h gibt es diese Art Alias:

typedef unsigned long int UINT4; 

Auf einem Linux x86_64-System (die Sie verwenden), das dazu geändert werden muss:

typedef unsigned int UINT4; 
+0

Wie soll das irgendetwas ändern? Die 'MD5_Update()' würde sowieso 'strlen (s)' Bytes verarbeiten. –

+0

Ändert irgendeine Funktion "s"? Willst du damit sagen, dass dieses Programm undefiniertes Verhalten anruft? –

+0

@CodePainters anscheinend ist die Implementierung gebrochen und mehr als die Länge gelesen, die Sie in 'dataLen' übergeben. – ouah