文章目录

  • 使用OpenSSL推荐的EVP高级接口计算摘要
  • EvpDigest 类定义
    • 1.EvpDigest 头文件接口
    • 2.EvpDigest 类函数实现
    • 3.使用 EvpDigest 类计算摘要,文件 EvpDigestTest.cpp
    • 4.摘要实现类简要说明
  • 总结

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

直接使用openssl evp接口对底层低级接口进行了抽象,比较便于封装成C++类,与之前的 Digest 类相比,不需要在各个方法调用之前使用 switch 进行摘要算法的判断

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

EvpDigest 类定义

1.EvpDigest 头文件接口

#ifndef OPENSSL_01_EVPDIGEST_H
#define OPENSSL_01_EVPDIGEST_H#include <openssl/evp.h>
#include "DigestAlgo.h"
#include "CommonFun.h"# define SM3_DIGEST_LENGTH    32class EvpDigest {public:/*** 创建摘要对象,指定摘要算法* @param algo 摘要算法*/explicit EvpDigest(DigestAlgo algo);virtual ~EvpDigest();/*** 更新数据* @param str* @return*/int digestUpdate(const std::string& str);/*** 计算摘要结果* @return*/int digestFinal();/*** 按照十六进制输出摘要值*/void showDigestHex();private:/*** 摘要算法*/DigestAlgo digestAlgo;/*** 摘要上下文*/EVP_MD_CTX* context;/*** 指定存储摘要算法*/const EVP_MD* evpMd;/*** 摘要值*/unsigned char* digest;/*** 摘要字节长度*/unsigned int digestLength;
};#endif //OPENSSL_01_EVPDIGEST_H

2.EvpDigest 类函数实现

#include <openssl/md5.h>
#include <openssl/sha.h>
#include <iostream>
#include "EvpDigest.h"EvpDigest::EvpDigest(DigestAlgo algo) : digestAlgo(algo) {switch (digestAlgo) {case DigestAlgo::MD5:digestLength = MD5_DIGEST_LENGTH;evpMd = EVP_md5();break;case DigestAlgo::SHA1:digestLength = SHA_DIGEST_LENGTH;evpMd = EVP_sha1();break;case DigestAlgo::SHA224:digestLength = SHA224_DIGEST_LENGTH;evpMd = EVP_sha224();break;case DigestAlgo::SHA256:digestLength = SHA256_DIGEST_LENGTH;evpMd = EVP_sha256();break;case DigestAlgo::SHA384:digestLength = SHA384_DIGEST_LENGTH;evpMd = EVP_sha384();break;case DigestAlgo::SHA512:digestLength = SHA512_DIGEST_LENGTH;evpMd = EVP_sha512();break;case DigestAlgo::SM3:digestLength = SM3_DIGEST_LENGTH;evpMd = EVP_sm3();break;default:std::cout << "摘要算法类型错误..." << std::endl;exit(EXIT_FAILURE);}digest = new unsigned char[digestLength];// 1.创建摘要上下文,分配空间context = EVP_MD_CTX_new();if (context == nullptr) {handleErrors();}// 2.用指定摘要算法初始化上下文指针int ret = EVP_DigestInit_ex(context, evpMd, nullptr);if (ret != 1) {handleErrors();}
}EvpDigest::~EvpDigest() {// 6.释放资源delete[] digest;EVP_MD_CTX_free(context);std::cout << "析构函数调用..." << std::endl;
}int EvpDigest::digestUpdate(const std::string& str) {// 3.传入待计算摘要的原始数据,update。可以调用多次 updateint ret = EVP_DigestUpdate(context, str.c_str(), str.size());if (ret != 1) {handleErrors();}return ret;
}int EvpDigest::digestFinal() {// 4.计算哈希值int ret = EVP_DigestFinal_ex(context, digest, &digestLength);if (ret != 1) {handleErrors();}return 0;
}void EvpDigest::showDigestHex() {// 5.将二进制哈希值转换为十六进制输出char* digestHex = new char[digestLength * 2 + 1];for (int i = 0; i < digestLength; ++i) {sprintf(&digestHex[i * 2], "%02x", digest[i]);}std::cout << "摘要值: " << digestHex << std::endl;delete[] digestHex;
}

3.使用 EvpDigest 类计算摘要,文件 EvpDigestTest.cpp

#include "EvpDigest.h"int main(int argc, char* argv[]) {EvpDigest digest(DigestAlgo::SHA256);digest.digestUpdate("123456");digest.digestUpdate("123456");digest.digestFinal();digest.showDigestHex();return 0;
}

4.摘要实现类简要说明

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

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

几个函数的使用步骤

  • 步骤1: 在构造函数中使用 EVP_XXX 函数给算法类型成员 evpMd 赋值,提供给 EVP_DigestInit_ex 函数的第二个参数,EVP_MD_CTX_new 给摘要上下文指针分配内存,同时根据算法类型记录摘要值字节长度
  • 步骤2: 在构造函数中使用 EVP_DigestInit_ex 函数指定摘要算法,并初始化上下文指针
  • 步骤3: 在 digestUpdate 函数中使用 EVP_DigestUpdate 函数更新数据,可以调用多次
  • 步骤4: 在 digestFinal 函数中使用 EVP_DigestFinal_ex 计算摘要
  • 步骤5: 补充一个比较重要的步骤,在析构函数中使用 EVP_MD_CTX_free 释放 EVP_MD_CTX_new 分配的资源,delete 运算符释放其他资源
  • 步骤6: showDigestHex 函数将二进制摘要值转换为十六进制输出

CommonFun.h 头文件中包含 handleErrors 函数的实现,请参考 前面的文章


总结

OpenSSL-3.0.3编程—封装EVP摘要计算为C++类EvpDigest相关推荐

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

    文章目录 使用OpenSSL推荐的EVP高级接口计算摘要 样例代码 推荐阅读 OpenSSL 官方 wiki 摘要实现类简要说明 handleErrors 函数 总结 使用OpenSSL推荐的EVP高 ...

  2. 基于openEuler的OpenSSL编译安装和编程基础

    文章目录 基于openEuler的OpenSSL编译安装和编程基础 OpenSSL编译安装 OpenSSL命令的使用 OpenSSL编程 简单测试 BASE64算法 作业 参考资料 基于openEul ...

  3. VC2008下使用OpenSSL 1.0.0g(免编译)

    摘要: 运行时库附加依赖项多线程(/MT)libeay32MT.lib ssleay32MT.lib多线程调试(/MTd)libeay32MTd.lib ssleay32... id="cp ...

  4. CloudSim3.0.3power编程examples及辅助类解析

    CloudSim3.0.3power编程examples及辅助类解析 注:本文为旧文的markdown重制版 power编程依赖的底层主要类(PowerDataCenter.PowerDCBroker ...

  5. python面向对象编程 -- 封装、继承

    面向对象编程 -- 封装.继承 面向对象编程三要素:封装.继承和多态.本文主要看和封装.继承相关的概念:在python中多态的概念比较模糊,本文不做讨论. 1 封装 封装:将数据和操作组装到一起,对外 ...

  6. 细说Android 4.0 NDK编程pdf

    下载地址:网盘下载 <细说Android 4.0 NDK编程>内容简介:通过NDK,应用程序可以非常方便地实现Java与C∕C++代码的相互沟通.<细说Android 4.0 NDK ...

  7. openssl / vs2019 编译 openssl 1.0.2u 过程说明

    一.准备 1.安装 perl http://strawberryperl.com/download/5.28.1.1/strawberry-perl-5.28.1.1-64bit.msi 2.下载 o ...

  8. vue 生成发布包_年轻人如何从0到1封装发布一个vue组件__Vue.js

    封装发布组件是前端开发中非常重要的能力,通过对常用组件的封装可以提升团队开发的效率,避免重复劳作且不方便维护.好的组件的抽象和封装能让组件得到更广泛和多环境兼容的应用. 本文讲述了如何一步步从0到1封 ...

  9. matlab usb cam,Matlab环境下使用USB2.0摄像头编程image acquisition tools(读书笔记) | 学步园...

    (1)Matlab环境下使用USB2.0摄像头编程 Matlab中的图像获取工具箱给我们提供了必要的函数,我们直接调用就可以了,主要就是简单的介绍如何使用该工具箱进行对USB2.0摄像头的编程. TA ...

最新文章

  1. 利用BH1750光度传感器测量一些发光体
  2. Algorithm:C++语言实现之贪心法算法相关问题
  3. while((ch=getchar())!=EOFch != '\n');消除非法输入
  4. 使用gparted live分区工具对VMware及ESXI(vsphere)虚拟机进行根目录扩容(可视化界面操作)
  5. flex页面布局练习--知乎
  6. openshift_在OpenShift上扩展Java EE微服务
  7. 基于java家教管理系统_基于jsp的家教信息管理-JavaEE实现家教信息管理 - java项目源码...
  8. java开发环境搭建--写给java新手
  9. 虚幻4 Object和序列化
  10. Linux操作Oracle(8)——Oracle数据库迁移全纪录(1) — 表空间 用户 权限迁移
  11. 遗传算法c语言 x^2,c语言遗传算法 解决 y=x2问题
  12. Excel中绘制斜线表头
  13. OpenCV显示中文字体
  14. php 完全前后端分离使用jwt,前后端分离,在 angular 8 中利用 JWT 进行身份认证
  15. Spark—15分钟教程
  16. AAAI最佳论文Informer 解读
  17. Android_版本控制_Git命令行介绍和使用说明
  18. 单片机开发-软件架构与系统设计(工程实现使用的也是轮询系统、前后台系统和多任务系统)
  19. 关于umdf 和 kmdf
  20. 《炬丰科技-半导体工艺》 双异质结双极晶体管的加速振荡

热门文章

  1. Wio Terminal 读取 AHT10 传感器
  2. Windows端pytorch镜像快速安装【清华源】
  3. java课程设计-文本编辑器
  4. 利用百度地图API制作房产酒店地图
  5. C++语言程序设计基础
  6. Tomcat 8(一)Tomcat常用配置
  7. JS更好的字符串排序(字母顺序+数字大小排序)
  8. 计算机一级考试:选择题汇总E(精简版)
  9. 解决cv保存图片中文名称乱码 cv2.imwrite cv2.imencode
  10. Uipath Studio流程设计器介绍