2013-04-08 14 views
6

Próbuję wygenerować skrót MD5 dla ciągu znaków "Hello World" przy użyciu oryginalnego/nietkniętego pliku md5.h i md5c.c z http://www.arp.harvard.edu. Ale mój wynik różni się od wszystkich narzędzi online md5, które przetestowałem. Co jest nie tak z tym kodem? Dziękuję Ci.Powracanie niewłaściwego skrótu MD5 w 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

Na marginesie - Mam skompilowany kod przeciwko implementacji MD5 OpenSSL - działa zgodnie z oczekiwaniami! Tak więc 'md5.c', którego spróbujesz użyć, może zostać po prostu złamane w ten czy inny sposób. –

Odpowiedz

1

Masz problem z dopełnieniem. Algorytm skrótu MD5 działa na blokach 512-bitowych. Kiedy twój ostatni blok jest mniejszy niż 512 bitów, musi być dopełniony. W twoim przykładzie pierwszy blok jest także ostatnim blokiem, ponieważ ma mniej niż 512 bitów.

Wyściółka to format nazywa się Merkle–Damgård construction.

Możesz znaleźć pseudo kod, który zawiera wypełnienie here.

+4

Czy 'MD5Finalize()' nie ma wykonać wszystkich niezbędnych wypełnień? –

+0

@CodePainters Tak, prawdopodobnie masz rację. – vipw

+0

@vipw, masz rację. Spróbuję później (moje dziecko płacze teraz w domu). Dzięki. – Pigaax

3

Jak wspomniano @vipw, występuje problem z dopełnieniem. Ta implementacja MD5 nie obsługuje poprawnie dopełniania dla rozmiarów komunikatów, które nie są wielokrotnością rozmiaru bloku MD5 (512-bitów/64 bajty).

Aby rozwiązać go na swojej stronie, należy wymienić:

const char *s = "Hello World"; 

przez

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

EDIT:

Było Druga kwestia związana z przenoszeniem w tej implementacji MD5. W md5.h istnieje tego typu alias:

typedef unsigned long int UINT4; 

W systemie x86_64 Linux (który używasz), to musi być zmienione w ten sposób:

typedef unsigned int UINT4; 
+0

Jak to ma zmienić cokolwiek? 'MD5_Update()' i tak przetwarzałoby 'strlen (s)' bytes. –

+0

Czy jakakolwiek funkcja modyfikuje 's' chociaż? Czy sugerujesz, że ten program wywołuje niezdefiniowane zachowanie? –

+0

@CodePainters podobno implementacja jest zepsuta i czytana więcej niż długość, którą przekazujesz w 'dataLen'. – ouah