인디노트

[c++] OpenSSL 라이브러리를 사용하여 C ++에서 SHA 해시 생성 본문

인증기술/PKI 기술

[c++] OpenSSL 라이브러리를 사용하여 C ++에서 SHA 해시 생성

인디개발자 2018. 10. 5. 09:56

OpenSSL에는 코드 예제가없는 끔찍한 documentation 가 있지만 여기에는 다음이 포함됩니다.

#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 호출).








다음은 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 함수를 호출하는 것보다 시간이 오래 걸리지 만 보편적이며 파일 스트림을 사용하여 다시 처리 할 수 ​​있으므로 모든 길이의 데이터를 처리 할 수 ​​있습니다.


반응형
Comments