Generate SHA hash in C++ using OpenSSL library

匿名 (未验证) 提交于 2019-12-03 02:12:02

问题:

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

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

回答1:

From the command line, it's simply:

printf "compute sha1" | openssl sha1 

You can invoke the library like this:

#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; } 



回答2:

OpenSSL has a horrible 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; } 

Usage:

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

Afterwards, md will contain the binary SHA-256 message digest. Similar code can be used for the other SHA family members, just replace "256" in the code.

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



回答3:

correct syntax at command line should be

echo -n "compute sha1" | openssl sha1 

otherwise you'll hash the trailing newline character as well.



回答4:

Here is OpenSSL example of calculating sha-1 digest 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;     } } 

Though it's longer than just calling SHA1 function from OpenSSL, but it's more universal and can be reworked for using with file streams (thus processing data of any length).



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!