使用OpenSSL库在C ++中生成SHA哈希
如何使用OpenSSL libarary生成SHA1或SHA2哈希?
我search谷歌,找不到任何function或示例代码。
从命令行,它只是:
printf "compute sha1" | openssl sha1
你可以像这样调用库:
#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; }
OpenSSL有一个可怕的文档 ,没有代码示例,但在这里你是:
#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; }
用法:
unsigned char md[SHA256_DIGEST_LENGTH]; // 32 bytes if(!simpleSHA256(<data buffer>, <data length>, md)) { // handle error }
之后, md
将包含二进制SHA-256消息摘要。 其他SHA家族成员可以使用类似的代码,只需在代码中replace“256”即可。
如果数据量较大,当然应该在数据块到达时提供数据块(多个SHA256_Update
调用)。
在命令行应该是正确的语法
echo -n "compute sha1" | openssl sha1
否则,你也将散列尾随的换行符。
以下是使用BIO计算sha-1摘要的OpenSSL示例:
#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; } }
虽然它不仅仅是调用OpenSSL的 SHA1
函数,但是它更具有通用性,可以重复使用文件stream(从而处理任意长度的数据)。