2013-04-08 40 views
6

Tôi đang cố gắng tạo băm MD5 cho một chuỗi "Xin chào thế giới" bằng cách sử dụng md5.h nguyên bản/không bị ảnh hưởng và md5c.c từ http://www.arp.harvard.edu. Nhưng kết quả của tôi khác với tất cả các công cụ trực tuyến md5 mà tôi đã thử nghiệm. Có gì sai mã này? Cảm ơn bạn.Trả lại băm MD5 sai trong 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

Như một mặt lưu ý - Tôi đã biên soạn mã của bạn chống lại việc triển khai MD5 của OpenSSL - nó hoạt động như mong đợi! Vì vậy, thực sự 'md5.c' bạn cố gắng sử dụng có thể chỉ đơn giản là bị hỏng cách này hay cách khác. –

Trả lời

1

Bạn gặp vấn đề với đệm. Thuật toán băm MD5 hoạt động trên các khối 512 bit. Khi khối cuối cùng của bạn nhỏ hơn 512 bit, nó cần phải được đệm. Trong ví dụ của bạn, khối đầu tiên cũng là khối cuối cùng vì nó nhỏ hơn 512 bit.

Đệm là định dạng được gọi là Merkle–Damgård construction.

Bạn có thể tìm thấy một số mã giả bao gồm đệm here.

+4

'MD5Finalize()' có phải thực hiện tất cả các phần đệm cần thiết không? –

+0

@CodePainters Vâng, có lẽ bạn đã đúng. – vipw

+0

@ vipw, bạn nói đúng. tôi sẽ thử nó sau này (con tôi đang khóc ở nhà). Cảm ơn. – Pigaax

3

Như @vipw đã đề cập có vấn đề với đệm. Triển khai MD5 này không quản lý đúng cách đệm cho kích thước thư không phải là bội số của kích thước khối MD5 (512 bit/64 byte).

Để khắc phục nó về phía bạn, thay thế:

const char *s = "Hello World"; 

bởi

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

EDIT:

Có một vấn đề thứ hai liên quan đến tính di động trong việc thực hiện MD5 này. Trong md5.h có này loại bí danh:

typedef unsigned long int UINT4; 

Trên một hệ thống x86_64 Linux (mà bạn đang sử dụng), điều này phải được thay đổi như sau:

typedef unsigned int UINT4; 
+0

Làm thế nào để thay đổi bất cứ điều gì? 'MD5_Update()' sẽ xử lý 'strlen (s)' byte anyway. –

+0

Có chức năng nào sửa đổi 's' không? Bạn có ngụ ý rằng chương trình này gọi hành vi không xác định? –

+0

@CodePainters dường như việc triển khai bị hỏng và đọc nhiều hơn độ dài bạn vượt qua trong 'dataLen'. – ouah