Generate SHA hash in C ++ using OpenSSL library

How can I generate SHA1 or SHA2 hashes using OpenSSL libarary?

I searched google and could not find any function code or example.

+63
c ++ cryptography
May 28 '09 at
source share
4 answers

On the command line, this is simple:

printf "compute sha1" | openssl sha1 

You can call the library as follows:

 #include <stdio.h> #include <string.h> #include <openssl/sha.h> int main() { unsigned char ibuf[] = "compute sha1"; unsigned char obuf[20]; SHA1(ibuf, strlen(ibuf), obuf); int i; for (i = 0; i < 20; i++) { printf("%02x ", obuf[i]); } printf("\n"); return 0; } 

+69
May 28 '09 at 5:54 a.m.
source share

OpenSSL has terrible documentation with no code examples, but here you are:

 #include <openssl/sha.h> bool simpleSHA256(void* input, unsigned long length, unsigned char* md) { SHA256_CTX context; if(!SHA256_Init(&context)) return false; if(!SHA256_Update(&context, (unsigned char*)input, length)) return false; if(!SHA256_Final(md, &context)) return false; return true; } 

Using:

 unsigned char md[SHA256_DIGEST_LENGTH]; // 32 bytes if(!simpleSHA256(<data buffer>, <data length>, md)) { // handle error } 

Subsequently, md will contain a binary SHA-256 message digest. Similar code can be used for other members of the SHA family, just replace “256” in the code.

If you have larger data, you should of course feed the chunks of data as they arrive (several calls to SHA256_Update ).

+47
Feb 14 '10 at 19:34
source share

The correct syntax on the command line should be

 echo -n "compute sha1" | openssl sha1 

otherwise, you also save the newline character.

+3
Apr 29 2018-11-21T00:
source share

Here is an example of OpenSSL for calculating the sha-1 array using BIO:

 #include <openssl/bio.h> #include <openssl/evp.h> std::string sha1(const std::string &input) { BIO * p_bio_md = nullptr; BIO * p_bio_mem = nullptr; try { // make chain: p_bio_md <-> p_bio_mem p_bio_md = BIO_new(BIO_f_md()); if (!p_bio_md) throw std::bad_alloc(); BIO_set_md(p_bio_md, EVP_sha1()); p_bio_mem = BIO_new_mem_buf((void*)input.c_str(), input.length()); if (!p_bio_mem) throw std::bad_alloc(); BIO_push(p_bio_md, p_bio_mem); // read through p_bio_md // read sequence: buf <<-- p_bio_md <<-- p_bio_mem std::vector<char> buf(input.size()); for (;;) { auto nread = BIO_read(p_bio_md, buf.data(), buf.size()); if (nread < 0) { throw std::runtime_error("BIO_read failed"); } if (nread == 0) { break; } // eof } // get result char md_buf[EVP_MAX_MD_SIZE]; auto md_len = BIO_gets(p_bio_md, md_buf, sizeof(md_buf)); if (md_len <= 0) { throw std::runtime_error("BIO_gets failed"); } std::string result(md_buf, md_len); // clean BIO_free_all(p_bio_md); return result; } catch (...) { if (p_bio_md) { BIO_free_all(p_bio_md); } throw; } } 

Although it is longer than just calling the SHA1 function from OpenSSL, it is more universal and can be redesigned for use with file streams (thus processing data of any length).

+1
Dec 10 '15 at 12:18
source share



All Articles