OpenSSL-3.0.3编程—采用EVP方式计算数据摘要


使用OpenSSL推荐的EVP高级接口计算摘要

OpenSSL 源代码中低级接口被标记为废弃 deprecated,为了与 OpenSSL 保持同步,记录一下 OpenSSL 高级接口计算摘要的方法。低级接口的使用请参考前面的文章——OpenSSL-3.0.3编程—计算数据摘要

直接使用openssl API 计算摘要一般包含如下三个步骤,与低级接口类似,多了一步分配空间

  1. 创建摘要上下文,分配空间
  2. 初始化指定摘要算法的上下文
  3. 更新数据。可以添加多次,比如"hello, world" 可以分两次更新,可以参考如下代码
  4. 计算摘要值。对第3步更新的所有的数据计算摘要,通过传出参数返回摘要值
  5. 使用 EVP_MD_CTX_free 释放资源(重要)
  6. 将第4步计算的二进制摘要值转换为十六进制或Base64输出,本步骤可省略,看具体需要采用合适的方式

样例代码

#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/md5.h>
#include <string.h>
#include <iostream>
#include "CommonFun.h"

int main(int argc, char* argv[]) {
    // 1.创建摘要上下文,分配空间
    EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
    if (mdctx == nullptr) {
        handleErrors();
    }

    // 2.用指定摘要算法初始化上下文指针
    int retInit = EVP_DigestInit_ex(mdctx, EVP_sha384(), nullptr);
    if (retInit != 1) {
        handleErrors();
    }

    const char* data = "123456";
    // 3.传入待计算摘要的原始数据,update。可以调用多次 update
    int retUpdate = EVP_DigestUpdate(mdctx, data, strlen(data));
    if (retUpdate != 1) {
        handleErrors();
    }
    unsigned char* md = new unsigned char[MD5_DIGEST_LENGTH];
    unsigned int digestLength = MD5_DIGEST_LENGTH;
    // 4.计算哈希值
    int retFinal = EVP_DigestFinal_ex(mdctx, md, &digestLength);
    if (retFinal != 1) {
        handleErrors();
    }
    // 5.将二进制哈希值转换为十六进制输出
    char* mdHex = new char[digestLength * 2 + 1];
    for (int i = 0; i < digestLength; ++i) {
        sprintf(&mdHex[i * 2], "%02x", md[i]);
    }
    std::cout << "摘要值: " << mdHex << std::endl;
    delete[] mdHex;
    EVP_MD_CTX_free(mdctx);
	return 0;
}

推荐阅读 OpenSSL 官方 wiki

这个 OpenSSL wiki 网站包含一些简单的 sdk api 使用,它的更新好像不是很及时,不过初学者可以借鉴


摘要实现类简要说明

函数 EVP_DigestInit_ex 的第二个参数可以指定摘要算法,如 EVP_sha1EVP_sha224EVP_sha256EVP_sha3_256EVP_sm3……另外,EVP_sha256 与 EVP_sha3_256 有啥区别还没明白,以后明白了再补充

特别说明: OpenSSL3 里面包含国密算法,如 sm2、sm3、sm4,若要使用sm3计算摘要,可以在函数 EVP_DigestInit_ex 第二个参数传入 EVP_sm3()

几个函数的使用步骤

  • 步骤1: 使用 EVP_MD_CTX_new 函数给摘要上下文指针分配空间
  • 步骤2: 使用 EVP_DigestInit_ex 函数指定摘要算法,并初始化上下文指针
  • 步骤3: 使用 EVP_DigestUpdate 函数更新数据,可以调用多次
  • 步骤4: 使用 EVP_DigestFinal_ex 计算摘要
  • 步骤5: 补充一个比较重要的步骤,使用 EVP_MD_CTX_free 释放资源
  • 步骤6: (可省略)将二进制摘要值转换为十六进制输出

handleErrors 函数

#include <iostream>
#include <openssl/err.h>

void handleErrors(void) {
    ERR_print_errors_fp(stderr);
    abort();
}

总结

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值