반응형
OpenSSL 라이브러리를 사용하여 C ++에서 SHA 해시 생성
OpenSSL 라이브러리를 사용하여 SHA1 또는 SHA2 해시를 생성하려면 어떻게 해야합니까?
Google을 검색했는데 기능이나 예제 코드를 찾을 수 없습니다.
명령 줄에서 간단하게 :
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 제품군에 대해서도 유사한 코드를 사용할 수 있습니다. 코드에서 "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
함수를 호출하는 것보다 더 길지만 더 보편적이며 파일 스트림과 함께 사용하도록 재 작업 할 수 있습니다 (따라서 모든 길이의 데이터 처리).
큰 파일에 대한 @AndiDog 버전의 조정 :
static const int K_READ_BUF_SIZE{ 1024 * 16 };
std::optional<std::string> CalcSha256(std::string filename)
{
// Initialize openssl
SHA256_CTX context;
if(!SHA256_Init(&context))
{
return std::nullopt;
}
// Read file and update calculated SHA
char buf[K_READ_BUF_SIZE];
std::ifstream file(filename, std::ifstream::binary);
while (file.good())
{
file.read(buf, sizeof(buf));
if(!SHA256_Update(&context, buf, file.gcount()))
{
return std::nullopt;
}
}
// Get Final SHA
unsigned char result[SHA256_DIGEST_LENGTH];
if(!SHA256_Final(result, &context))
{
return std::nullopt;
}
// Transform byte-array to string
std::stringstream shastr;
shastr << std::hex << std::setfill('0');
for (const auto &byte: result)
{
shastr << std::setw(2) << (int)byte;
}
return shastr.str();
}
참고 URL : https://stackoverflow.com/questions/918676/generate-sha-hash-in-c-using-openssl-library
반응형
'Programing' 카테고리의 다른 글
NULL 또는 IS NULL이있는 IN 절 (0) | 2020.11.08 |
---|---|
최신 Java와 배열 목록의 동일성을 비교하는 방법은 무엇입니까? (0) | 2020.11.08 |
postgresql의 Rownum (0) | 2020.11.08 |
Backbone.js 컬렉션에서 fetch ()를 호출하면 어떤 이벤트가 트리거됩니까? (0) | 2020.11.08 |
Eclipse는 해결되지 않은 컴파일 문제가있는 클래스를 어떻게 만들 수 있습니까? (0) | 2020.11.08 |