简体   繁体   中英

SHA256 and RIPEMD160HASH in c program

I wrote ac program to perform sha256 hash on a char array and then perform ripemd160 hash on the output of sha256 hash function.

here is my code:

#include <stdio.h>
#include <string.h>
#include <openssl/sha.h>
#include <openssl/ripemd.h>

int main(){
int c;

const unsigned char* rawdata = "046EAF0968AA895ADDFEE599566F0B880242461D1377F4887C9B84631E13067B96DB18C41E0C208F8D12EBCC3F99F2522903AF6105833E4CBADE9D6A1D0F039187";
unsigned long n = strlen(rawdata);
unsigned char *d = SHA256(rawdata, strlen(rawdata), 0);

for (c = 0; c < 32; c++){
    printf("%02x", d[c]);
}
putchar('\n');

unsigned char md[32];
unsigned char* pmd = RIPEMD160(d, strlen(d), md);

int i;
for (i = 0; i < 20; i++)
    printf("%02x", pmd[i]);
putchar('\n');

return 0;

}

the problem is in this line :

unsigned char *d = SHA256(raw-data, strlen(raw-data), 0); when I pass the d pointer which is the output of the sha256 function to RIPEMD160 function the resulting hash output of RIPEMD160 function becomes wrong. Can anyone tell me why this is happening? And how can correct my code to print and store my ripems160 hash in a char array?

Here is what I have tried:

the resulting hash output of the string "046EAF0968AA895ADDFEE599566F0B880242461D1377F4887C9B84631E13067B96DB18C41E0C208F8D12EBCC3F99F2522903AF6105833E4CBADE9D6A1D0F039187"

is : 37a0df85d5ccf7cb5f92b53aa3f223d76c115a844ed52d8978deecd2ecb3e406

which is correct.

But the ripemd160 hash of "37a0df85d5ccf7cb5f92b53aa3f223d76c115a844ed52d8978deecd2ecb3e406" should be

"4ecc9d3eea56b0af96b6db612b76911858dcb40d" but my is wrong.

here is the output of my code when compiled with this command

"gcc sha256.c -lssl -lcrypto -Wno-deprecated-declarations"

output:

37a0df85d5ccf7cb5f92b53aa3f223d76c115a844ed52d8978deecd2ecb3e406 63bb23be08e2c097008c4c272cc56c14e5656831

the second string "63bb23be08e2c097008c4c272cc56c14e5656831" is ripemd160 hash which is wrong

Your problem is on this line:

unsigned char* pmd = RIPEMD160(d, strlen(d), md);

strlen finds the length of a printable string by looking for the terminating \\0 . But the data in d is binary data. It is not terminated by \\0 and may contain that value as part of the data. You should replace strlen(d) with the actual value for the length of a SHA256 hash (32).

Update:

It seems your "correct" output can be achieved by doing some further processing of the SHA256 output. I don't know where you got your test vector from but it seems the expected input into the RIPEMD160 function is the SHA256 output converted into a printable string - and hashing that string.

These modifications seem to achieve the output that you are expecting:

--- doublehash1.c   2020-03-21 00:50:11.882423750 +0000
+++ doublehash.c    2020-03-21 00:49:36.778485523 +0000
@@ -9,14 +9,16 @@
     const unsigned char* rawdata = "046EAF0968AA895ADDFEE599566F0B880242461D1377F4887C9B84631E13067B96DB18C41E0C208F8D12EBCC3F99F2522903AF6105833E4CBADE9D6A1D0F039187";
     unsigned long n = strlen(rawdata);
     unsigned char *d = SHA256(rawdata, strlen(rawdata), 0);
+    unsigned char data[65], *p;

-    for (c = 0; c < 32; c++){
-        printf("%02x", d[c]);
+    for (c = 0, p = data; c < 32; c++, p += 2){
+        sprintf(p, "%02x", d[c]);
     }
+    printf("%s", data);
     putchar('\n');

     unsigned char md[32];
-    unsigned char* pmd = RIPEMD160(d, strlen(d), md);
+    unsigned char* pmd = RIPEMD160(data, strlen(data), md);

     int i;
     for (i = 0; i < 20; i++)

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