简体   繁体   English

字符串的MD5在C中输出错误

[英]MD5 of string gives wrong output in C

My question is similar to this one here but I'm using openssl/md5.h 我的问题与类似,但我使用的是openssl / md5.h

I'm trying to get user input and find its MD5 hash. 我正在尝试获取用户输入并找到其MD5哈希值。 Here's my code: 这是我的代码:

#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;
}

This code compiles and runs successfully on my Mac. 此代码在我的Mac上成功编译并运行。 When I give 12345 as input to the binary, the output I get is d577273ff885c3f84dadb8578bb41399 : 当我给12345作为二进制文件的输入时,我得到的输出是d577273ff885c3f84dadb8578bb41399

 $ ./md5code
 Enter the password: 12345
 12345

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

However, when I run md5 -s 12345 , the output I get is 827ccb0eea8a706c4c34a16891f84e7b which is also the output I get when I check the MD5 using online tools. 但是,当我运行md5 -s 12345 ,我得到的输出是827ccb0eea8a706c4c34a16891f84e7b ,这也是我使用在线工具检查MD5时得到的输出。

My initial thoughts were that this is because of the NULL terminator so I calculated the MD5 of the string with them: 我最初的想法是,这是因为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

As you can see, none of the MD5s match the one that I'm getting from my code. 正如您所看到的,MD5中没有一个与我从代码中获得的MD5匹配。 Can anyone help me figure out what is wrong and how to fix it? 任何人都可以帮我弄清楚出了什么问题以及如何解决它? Thanks! 谢谢!

Note: I'm well aware that MD5 is a very weak and broken hash and should not be used for any real purposes. 注意:我很清楚MD5是一个非常弱且破坏的哈希值,不应该用于任何实际目的。 I'm doing this just to understand basic coding. 我这样做只是为了理解基本编码。

Take a look at the output these two OpenSSL commands (which you can also replace with openssl dgst -md5 commands to get the same output): 看看这两个OpenSSL命令的输出(您也可以用openssl dgst -md5命令替换openssl dgst -md5以获得相同的输出):

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

The latter one is the one you are looking for. 后者是你正在寻找的那个。 The difference between echo and printf is that the former adds a newline and the latter does not: 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

So it is the 0a that is causing you the troubles. 所以它是0a导致你的麻烦。

Two additional remarks: the <(echo 12345) construct is an example of Process Substitution and instead of printf , you can also use echo -n . 另外两个备注: <(echo 12345)构造是Process Substitution的一个例子,你也可以使用echo -n代替printf The latter is not standardized though, as pointed out in a comment below. 然而,后者并未标准化,如下面的评论中所指出的那样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM