Generate SHA-3 hash in C++ using OpenSSL library

烈酒焚心 提交于 2019-12-10 10:40:12

问题


I've searched extensively for a code example that uses OpenSSL's recently implemented SHA-3 algorithm for hashing but couldn't find any. There are code examples on SHA-1 and SHA-3 but a quick search in the library folders reveal that there isn't even a SHA3 function name in OpenSSL v1.1.1?

I've searched everywhere but this is relatively new and I have not been able to track down any information specifically regarding the new algorithm.

I found this thread that Generate SHA hash in C++ using OpenSSL library covers SHA-1 and SHA-2 but there isn't actually a SHA3 function in the library - Keccak1600 seems like name for SHA-3?


回答1:


There is some generic sample code for generating a hash on this page:

https://wiki.openssl.org/index.php/EVP_Message_Digests

That particular code generates a SHA256 hash. To convert it to use SHA3 instead, replace the two instances of EVP_sha256() with one of EVP_sha3_224(), EVP_sha3_256(), EVP_sha3_384() or EVP_sha3_512() as appropriate.




回答2:


I have written a simple example which uses openssl SHA-3 implementation to calculate the digest of all the data read from stdin. With a command line parameter to specify SHA-3 digest length. Tested on Linux Parrot (distro based on Debian), libssl-dev 1.1.1c-1.

Link to the repository.

Or here is the source code:

#include <openssl/evp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
/*
 * building on Debian requires libssl-dev package (sudo apt install libssl-dev)
 */

#define BUF_SIZE 1024

#define HANDLE_ERROR(msg) { fprintf(stderr, "%s\n", msg); exit(EXIT_FAILURE); }
#define HANDLE_ERROR2(msg, mdctx) { fprintf(stderr, "%s\n", msg); EVP_MD_CTX_destroy(mdctx); exit(EXIT_FAILURE); }

int main(int argc,  char * const argv[]) {

    int opt;
    char * endptr;
    char buffer[BUF_SIZE];
    int bytes_read;

    EVP_MD_CTX * mdctx;
    int val;
    unsigned char * digest;
    unsigned int digest_len;
    EVP_MD * algo = NULL;

    while ((opt = getopt(argc, argv, "t:")) != -1) {
        switch (opt) {
        case 't':
            errno = 0;

            val = strtol(optarg, &endptr, 10);

            if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
                    || (errno != 0 && val == 0)) {
                perror("Wrong value for t parameter");
                exit(EXIT_FAILURE);
            }

            if (endptr == optarg) {
                fprintf(stderr, "No value was found for t parameter\n");
                exit(EXIT_FAILURE);
            }

            switch (val) {
            case 224:
                algo = EVP_sha3_224();
                break;
            case 256:
                algo = EVP_sha3_256();
                break;
            case 384:
                algo = EVP_sha3_384();
                break;
            case 512:
                algo = EVP_sha3_512();
                break;
            default:
                fprintf(stderr,"Wrong value for t parameter (valid values: 224, 256, 384, 512)");
                exit(EXIT_FAILURE);
            }

            break;
        default: /* '?' */
            fprintf(stderr, "Usage: %s [-t sha3_size]\n"
                    "Example program which calculates SHA-3 hash of data read from stdin.\n"
                    "Uses openssl implementation of SHA-3 algorithm.\n"
                    "sha3_size can be: 224, 256, 384, 512. Default is 256.\n",
                    argv[0]);
            exit(EXIT_FAILURE);
        }
    }

    if (algo == NULL) {
        algo = EVP_sha3_256();
    }


    if ((mdctx = EVP_MD_CTX_create()) == NULL) {
        HANDLE_ERROR("EVP_MD_CTX_create() error")
    }

    // initialize digest engine
    if (EVP_DigestInit_ex(mdctx, algo, NULL) != 1) { // returns 1 if successful
        HANDLE_ERROR2("EVP_DigestInit_ex() error", mdctx)
    }

    while ((bytes_read = read(STDIN_FILENO, buffer, BUF_SIZE)) > 0) { // read returns 0 on EOF, -1 on error
        // provide data to digest engine
        if (EVP_DigestUpdate(mdctx, buffer, bytes_read) != 1) { // returns 1 if successful
            HANDLE_ERROR2("EVP_DigestUpdate() error", mdctx)
        }

    }

    if (bytes_read == -1) {
        perror("read error");
        exit(1);
    }

    digest_len = EVP_MD_size(algo);

    if ((digest = (unsigned char *)OPENSSL_malloc(digest_len)) == NULL) {
        HANDLE_ERROR2("OPENSSL_malloc() error", mdctx)
    }

    // produce digest
    if (EVP_DigestFinal_ex(mdctx, digest, &digest_len) != 1) { // returns 1 if successful
        OPENSSL_free(digest);
        HANDLE_ERROR2("EVP_DigestFinal_ex() error", mdctx)
    }

    for (int i = 0; i < digest_len; i++) {
        printf("%02x", digest[i]);
    }

    OPENSSL_free(digest);
    EVP_MD_CTX_destroy(mdctx);

    return 0;
}


来源:https://stackoverflow.com/questions/51144505/generate-sha-3-hash-in-c-using-openssl-library

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!