简体   繁体   中英

MD5 of string gives wrong output in C

My question is similar to this one here but I'm using openssl/md5.h

I'm trying to get user input and find its MD5 hash. 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. When I give 12345 as input to the binary, the output I get is 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.

My initial thoughts were that this is because of the NULL terminator so I calculated the MD5 of the string with them:

$ 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. 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. 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):

$ 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:

$ 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.

Two additional remarks: the <(echo 12345) construct is an example of Process Substitution and instead of printf , you can also use echo -n . The latter is not standardized though, as pointed out in a comment below.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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