Reputation: 447
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
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
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