Siedler
Siedler

Reputation: 97

Different hash values for identical input using different OpenSSL evp.h functions

Using the following code, why do I get different hash values?

#include <iostream>
#include <cstring>
#include <openssl/evp.h>

# define SHA256_DIGEST_LENGTH    32


using namespace std;

static void hex_print(const char *name, const unsigned char *buf, size_t len)
{
    size_t i;
    fprintf(stdout, "%s ", name);
    for (i = 0; i < len; i++)
        fprintf(stdout, "%02X", buf[i]);
    fputs("\n", stdout);
}

int main (int argc, char *argv[]) 
{   
    EVP_MD_CTX *ctx;
    //const EVP_MD *evp_md = EVP_sha256();
    char *msg = (char*)"I have the high ground...";
    unsigned int msg_size = strlen(msg);
    unsigned char digest_a[SHA256_DIGEST_LENGTH] = {0};
    unsigned char digest_b[SHA256_DIGEST_LENGTH] = {0};

    cout << "message: " << msg << endl;
    cout << "length: " << msg_size << endl;

    ctx = EVP_MD_CTX_new();
    EVP_DigestInit_ex(ctx, EVP_sha256(), NULL);
    EVP_DigestUpdate(ctx, msg, msg_size);
    EVP_DigestFinal_ex(ctx, digest_a, &msg_size);

    hex_print("sha256: ", digest_a, SHA256_DIGEST_LENGTH);

    
    EVP_Digest (msg, msg_size, digest_b, NULL, EVP_sha256 (), NULL);
    hex_print ("sha256: ", digest_b, SHA256_DIGEST_LENGTH);

    EVP_MD_CTX_free(ctx);

    return EXIT_SUCCESS;
}

Compiled on Ubuntu 20.04 LTS using gcc

g++ -Wall -g -o test test.cpp -I/usr/include/openssl -L/usr/lib/x86_64-linux-gnu l:libcrypto.so

Output:

message: I have the high ground...
length: 25
sha256:  2873FC569EFBE61AC67A1247CCBAE0AE94BE97D227D1ECEF3C9E93A8EA3CAD33
sha256:  F13852B3A521A6D08169AAA42525AA63FEF87D8A22418A25A8E19F3FD15E750D

When I paste the string into an online tool such as https://emn178.github.io/online-tools/sha256.html, the "correct" hash seems to be the first one:

2873fc569efbe61ac67a1247ccbae0ae94be97d227d1ecef3c9e93a8ea3cad33

Can anyone explain me why this is happening? Thanks!

Upvotes: 1

Views: 884

Answers (1)

Botje
Botje

Reputation: 30807

The call EVP_DigestFinal_ex(ctx, digest_a, &msg_size) overwrites msg_size to SHA256_DIGEST_LENGTH, which is not equal to the original 25.

You then go on to use msg_size as if it was still the original value.

Upvotes: 2

Related Questions