2013-04-08 5 views
6

Sto cercando di generare MD5 hash per una stringa "Ciao Mondo" utilizzando il md5.h originale/intatta e md5c.c da http://www.arp.harvard.edu. Ma il mio risultato differisce da tutti gli strumenti online md5 che ho testato. Cosa c'è di sbagliato in questo codice? Grazie.Tornando sbagliato hash MD5 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

Come nota a margine - che ho compilato il codice contro l'implementazione MD5 di OpenSSL - funziona come previsto! Quindi infatti 'md5.c' che si tenta di utilizzare potrebbe semplicemente essere rotto in un modo o nell'altro. –

risposta

1

Si è verificato un problema con il riempimento. L'algoritmo di hash MD5 funziona su blocchi da 512 bit. Quando il blocco finale è inferiore a 512 bit, deve essere riempito. Nell'esempio, il primo blocco è anche l'ultimo blocco perché è inferiore a 512 bit.

Il formato del riempimento è denominato Merkle–Damgård construction.

È possibile trovare alcuni pseudo-codice che include il padding here.

+4

Non è necessario che 'MD5Finalize()' esegua tutto il riempimento necessario? –

+0

@CodePainters Sì, probabilmente hai ragione. – vipw

+0

@vipw, hai ragione. lo proverò più tardi (mio figlio sta piangendo ora a casa). Grazie. – Pigaax

3

Come @vipw menzionato, c'è un problema con il padding. Questa implementazione MD5 non gestisce correttamente il riempimento per le dimensioni dei messaggi che non sono un multiplo di una dimensione di blocco MD5 (512 bit/64 byte).

per risolvere il problema dalla vostra parte, sostituire:

const char *s = "Hello World"; 

da

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

EDIT:

c'era un secondo problema relativo alla portabilità in questa implementazione MD5. In md5.h c'è questo tipo di alias:

typedef unsigned long int UINT4; 

Su un sistema Linux x86_64 (che si sta utilizzando), questo deve essere cambiato in questo:

typedef unsigned int UINT4; 
+0

Come è possibile che cambi qualcosa? 'MD5_Update()' elaborerebbe comunque i byte 'strlen (s)'. –

+0

Qualunque funzione modifica 's'? Stai insinuando che questo programma invochi un comportamento indefinito? –

+0

@CodePainters a quanto pare l'implementazione è interrotta e legge più della lunghezza che passi in 'dataLen'. – ouah