簡體   English   中英

字符串的MD5在C中輸出錯誤

[英]MD5 of string gives wrong output in C

我的問題與類似,但我使用的是openssl / md5.h

我正在嘗試獲取用戶輸入並找到其MD5哈希值。 這是我的代碼:

#include <stdio.h>
#include <openssl/md5.h>
#include <stdlib.h>
#include <string.h>

void MD5hash(unsigned char *data, unsigned int dataLen, unsigned char *digest) {
    MD5_CTX c;
    MD5_Init(&c);
    MD5_Update(&c, data, dataLen);
    MD5_Final(digest, &c);
}

int main(){
    unsigned char md5_hash[MD5_DIGEST_LENGTH];
    char *input = NULL;
    int i, read;
    size_t len; 

    printf("Enter the password: ");
    read = getline(&input, &len, stdin);

    unsigned int str_length = (unsigned int)strlen(input);
    if(-1 != read)
        puts(input);
    else
        printf("Received no input\n");

    printf("Size read: %d Len: %zu String Length: %u\n", read, len, str_length);

    MD5hash((unsigned char *)input, str_length, md5_hash);

    printf("MD5 hash is: ");
    for(i = 0; i < MD5_DIGEST_LENGTH; i++){
        printf("%02x", md5_hash[i]);
    } 
    printf("\n");
    free(input);

    return 0;
}

此代碼在我的Mac上成功編譯並運行。 當我給12345作為二進制文件的輸入時,我得到的輸出是d577273ff885c3f84dadb8578bb41399

 $ ./md5code
 Enter the password: 12345
 12345

 Size read: 6 Len: 8
 String Length: 6
 MD5 hash is: d577273ff885c3f84dadb8578bb41399     

但是,當我運行md5 -s 12345 ,我得到的輸出是827ccb0eea8a706c4c34a16891f84e7b ,這也是我使用在線工具檢查MD5時得到的輸出。

我最初的想法是,這是因為NULL終止符所以我用它們計算了字符串的MD5:

$ md5 -s 12345
MD5 ("12345") = 827ccb0eea8a706c4c34a16891f84e7b
$md5 -s "12345\0"
MD5 ("12345\0") = b04fd4a8d62d25c4b69616ba7f5c5092
$md5 -s 12345\0
MD5 ("123450") = 149787a6b7986f31b3dcc0e4e857cd2a
$md5 -s "12345 "
MD5 ("12345 ") = 43d6757765116456c1c49310cbf8070d
$ md5 -s "12345\n"
MD5 ("12345\n") = 5d44fc965c76c70d2ebe72b4129bc0cd

正如您所看到的,MD5中沒有一個與我從代碼中獲得的MD5匹配。 任何人都可以幫我弄清楚出了什么問題以及如何解決它? 謝謝!

注意:我很清楚MD5是一個非常弱且破壞的哈希值,不應該用於任何實際目的。 我這樣做只是為了理解基本編碼。

看看這兩個OpenSSL命令的輸出(您也可以用openssl dgst -md5命令替換openssl dgst -md5以獲得相同的輸出):

$ md5 <(echo 12345)
MD5 (/dev/fd/63) = d577273ff885c3f84dadb8578bb41399
$ md5 <(printf 12345)
MD5 (/dev/fd/63) = 827ccb0eea8a706c4c34a16891f84e7b

后者是你正在尋找的那個。 echoprintf之間的區別在於前者添加換行符而后者不添加換行符:

$ hexdump -C <(echo 12345)
00000000  31 32 33 34 35 0a                                 |12345.|
00000006
$ hexdump -C <(printf 12345)
00000000  31 32 33 34 35                                    |12345|
00000005

所以它是0a導致你的麻煩。

另外兩個備注: <(echo 12345)構造是Process Substitution的一個例子,你也可以使用echo -n代替printf 然而,后者並未標准化,如下面的評論中所指出的那樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM