Générer SHA hash en C++ en utilisant la bibliothèque OpenSSL

Comment puis-je générer des hachures SHA1 ou SHA2 en utilisant le OpenSSL libarary?

j'ai cherché google et n'ai pas pu trouver de fonction ou d'exemple de code.

63
demandé sur Uli Köhler 2009-05-28 04:45:42

4 réponses

de la ligne de commande, c'est simplement:

printf "compute sha1" | openssl sha1

vous pouvez invoquer la bibliothèque comme ceci:

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

72
répondu brianegge 2013-05-20 19:12:55

OpenSSL a une horrible documentation sans exemples de code, mais vous êtes ici:

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

Utilisation:

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

après, md contiendra le condensé de messages binaires SHA-256. Un code similaire peut être utilisé pour les autres membres de la famille SHA, il suffit de remplacer "256" dans le code.

si vous avez des données plus grandes, vous devez bien sûr alimenter des morceaux de données à mesure qu'ils arrivent (plusieurs SHA256_Update appels).

51
répondu AndiDog 2018-05-22 08:21:35

la syntaxe correcte à la ligne de commande devrait être

echo -n "compute sha1" | openssl sha1

sinon tu vas aussi bousiller le personnage de newline.

2
répondu mecano 2011-04-29 21:58:07

Voici OpenSSL exemple de calcul 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;
    }
}

bien qu'il soit plus long que de simplement appeler SHA1 fonction de OpenSSL , mais il est plus universel et peut être retravaillé pour l'utilisation avec des flux de fichiers (donc le traitement des données de n'importe quelle longueur).

1
répondu anton_rh 2015-12-10 12:18:23