4

我已经广泛搜索了一个使用 OpenSSL 最近实现的 SHA-3 算法进行散列但找不到任何代码示例。有关于 SHA-1 和 SHA-3 的代码示例,但在库文件夹中快速搜索会发现 OpenSSL v1.1.1 中甚至没有 SHA3 函数名称?

我到处搜索,但这是相对较新的,我无法找到任何专门关于新算法的信息。

我发现使用 OpenSSL 库在 C++ 中生成 SHA 哈希的线程涵盖 SHA-1 和 SHA-2,但库中实际上没有 SHA3 函数 - Keccak1600 似乎是 SHA-3 的名称?

4

4 回答 4

2

在 Ubuntu 18.04 上,libssl-dev安装:

//main.cpp

#include <iostream>
#include <向量>
#include <sstream> //对于 std::ostringstream
#include <iomanip> //用于 std::setw、std::hex 和 std::setfill
#include <openssl/evp.h> //用于所有其他 OpenSSL 函数调用
#include <openssl/sha.h> //对于 SHA512_DIGEST_LENGTH

//帮助函数将摘要字节打印为十六进制字符串
std::string bytes_to_hex_string(const std::vector<uint8_t>& bytes)
{
    std::ostringstream 流;
    对于(uint8_t b:字节)
    {
        流 << std::setw(2) << std::setfill('0') << std::hex << static_cast<int>(b);
    }
    返回流.str();
}

//执行SHA3-512哈希
std::string sha3_512(const std::string& 输入)
{
    uint32_t 摘要长度 = SHA512_DIGEST_LENGTH;
    常量 EVP_MD* 算法 = EVP_sha3_512();
    uint8_t* 摘要 = static_cast<uint8_t*>(OPENSSL_malloc(digest_length));
    EVP_MD_CTX* 上下文 = EVP_MD_CTX_new();
    EVP_DigestInit_ex(上下文,算法,nullptr);
    EVP_DigestUpdate(context, input.c_str(), input.size());
    EVP_DigestFinal_ex(context, 摘要, &digest_length);
    EVP_MD_CTX_destroy(上下文);
    std::string 输出 = bytes_to_hex_string(std::vector<uint8_t>(digest, digest + digest_length));
    OPENSSL_free(摘要);
    返回输出;
}

主函数()
{
    std::string 输出 = sha3_512(std::string("abcdef"));
    std::cout << 输出 << "\n";
    返回0;
}

链接-lssl-lcrypto编译此代码:

/usr/bin/g++-10 main.cpp -lssl -lcrypto

输出:

01309a45c57cd7faef9ee6bb95fed29e5e2e0312af12a95fffeee340e5e5948b4652d26ae4b75976a53cc1612141af6e24df36517a61f46a1a05f59cf667046a

使用此工具验证输出:https ://emn178.github.io/online-tools/sha3_512.html

于 2020-06-27T04:31:06.107 回答
1

在此页面上有一些用于生成哈希的通用示例代码:

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

该特定代码生成 SHA256 哈希。要将其转换为使用 SHA3,请将 的两个实例替换为、或中EVP_sha256()的一个。EVP_sha3_224()EVP_sha3_256()EVP_sha3_384()EVP_sha3_512()

于 2018-07-03T08:29:54.897 回答
0

安装 openssl 并配置后PATH,包含<openssl/evp.h>在您的源文件中。是描述和示例。

于 2021-08-31T17:06:28.557 回答
0

我写了一个简单的例子,它使用 openssl SHA-3 实现来计算从标准输入读取的所有数据的摘要。使用命令行参数指定 SHA-3 摘要长度。在 Linux Parrot(基于 Debian 的发行版)、libssl-dev 1.1.1c-1 上测试。

链接到存储库

或者这里是源代码:

#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;
}
于 2019-06-26T15:44:28.010 回答