Как я могу генерировать хэши SHA1 или SHA2 с помощью OpenSSL libarary?
Я искал google и не смог найти какой-либо код функции или примера.
Как я могу генерировать хэши SHA1 или SHA2 с помощью OpenSSL libarary?
Я искал 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
в противном случае вы также сохраните символ новой строки.
Вот пример OpenSSL для вычисления массива sha-1 с помощью 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;
    }
}
Хотя это длиннее, чем просто вызов функции  SHA1 из OpenSSL, но более универсальный и может быть переработан для использования с файловыми потоками (таким образом, обработка данных любой длины).