Bryce
Bryce

Reputation: 447

SHA1 error implementation in C

I have been working on getting the sha1() function working from openssl/sha.h however I am getting random output and some warning. I have read quite a bit and tried some of the example codes but I get warning on all of it and it doesn't display correctly.

Here is code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <openssl/sha.h>

int main() 
{ 
const unsigned char data[] = "Hello, World";
unsigned long length = sizeof(data);
unsigned char  hash[SHA_DIGEST_LENGTH];
SHA1(data, length, hash);
printf("%02x \n", hash);
return 0;

}

Below is the warning I am getting:

sha.c: In function ‘main’:
sha.c:12: warning: ‘SHA1’ is deprecated (declared at /usr/include/openssl/sha.h:124)
sha.c:13: warning: format ‘%02x’ expects type ‘unsigned int’, but argument 2 has type   ‘unsigned char *’
sha.c:13: warning: format ‘%02x’ expects type ‘unsigned int’, but argument 2 has type ‘unsigned char *’

When I run it and I get the output: 62652b34

Any help would be great!

Upvotes: 1

Views: 4818

Answers (3)

user365268
user365268

Reputation:

It also took me a while before I figured it all out. The best way is to use EVP, it provides generic functions for almost everything.

#include <openssl/evp.h>

You need to call this im main before calling you hash function. To initialize your hashes. Otherwise openssl will complain that the algorithm is not available.

OpenSSL_add_all_algorithms();

mode must be "SHA256", "SHA512", "SHA1" as string. dataToHash is the input, dataSize is the size of the input, outHashed should already be allocated, the hash will be written there

unsigned int hash(const char *mode, const char* dataToHash, size_t dataSize, unsigned char* outHashed) {
    unsigned int md_len = -1;
    const EVP_MD *md = EVP_get_digestbyname(mode);
    if(NULL != md) {
        EVP_MD_CTX mdctx;
        EVP_MD_CTX_init(&mdctx);
        EVP_DigestInit_ex(&mdctx, md, NULL);
        EVP_DigestUpdate(&mdctx, dataToHash, dataSize);
        EVP_DigestFinal_ex(&mdctx, outHashed, &md_len);
        EVP_MD_CTX_cleanup(&mdctx);
    }
    return md_len;
}

A use example (this is not tested, I use the above code in a c++ wrapper)

const char *inData = "test data2";
unsigned char outHash[20]; // output is already allocated
hash("SHA1", inData, 10, outHash);

You shouldn't use the SHA1 method directly it is deprecated (your code could blow up with the next version). If you want to use your version you need to print each char as hex:

int i;
for(i=0; i<SHA_DIGEST_LENGTH; i++) {
    printf("%02x", hash[i]);
}

Upvotes: 2

WhozCraig
WhozCraig

Reputation: 66194

You can't dump the entire buffer that way. you need to loop it, such as below. The value you're getting for your output is actually the address of the hash buffer, which is clearly not what you're looking for. You want the hex-bytes in the buffer dumped as text

So...

int main()
{
    const unsigned char data[] = "Hello, World";
    unsigned long length = sizeof(data);
    unsigned char hash[SHA_DIGEST_LENGTH];
    SHA1(data, length, hash);

    int i=0;
    for (;i< sizeof(hash)/sizeof(hash[0]);++i)
        printf("%02x \n", hash[i]);

    return 0;

}

Regarding your warnings, the deprecation is because this interface is out-dated for performing the crypto-op you're attempting (SHA1). There are newer interfaces in OpenSSL that are current. Consider the EVP interface specifically.

Upvotes: 1

hmatar
hmatar

Reputation: 2419

printf("%02u \n", hash);

Remove warnings by printing unsigned char

Upvotes: 0

Related Questions