OpenSSL 中的 EVP_MD 学习笔记(针对1.1.1版本)
本文针对 OpenSSL 1.1.1 版,以下内容大部分来自对 \OpenSSL\html\man3\ 目录下 EVP_MD_ 开头的 html 文件的摘录和翻译。
-----------------------------------------------
EVP_MD_CTX 和 EVP_MD 的定义
在 OpenSSL 1.1.1 源码 \crypto\evp\evp_locl.h 中定义了结构体 evp_md_ctx_st, 如下:
struct evp_md_ctx_st {
const EVP_MD *digest;
ENGINE *engine;
unsigned long flags;
void *md_data;
EVP_PKEY_CTX *pctx;
int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
} /* EVP_MD_CTX */ ;
在 OpenSSL 1.1.1 源码 \crypto\include\internal\evp_int.h 中定义了结构体 evp_md_st,如下:
struct evp_md_st {
int type;
int pkey_type;
int md_size;
unsigned long flags;
int (*init) (EVP_MD_CTX *ctx);
int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
int (*final) (EVP_MD_CTX *ctx, unsigned char *md);
int (*copy) (EVP_MD_CTX *to, const EVP_MD_CTX *from);
int (*cleanup) (EVP_MD_CTX *ctx);
int block_size;
int ctx_size;
int (*md_ctrl) (EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
} /* EVP_MD */ ;
在 \include\openssl\ossl_typ.h 中定义了以下宏:
typedef struct evp_md_st EVP_MD;
typedef struct evp_md_ctx_st EVP_MD_CTX;
-----------------------------------------------
和计算摘要有关的部分函数
EVP_MD_CTX *EVP_MD_CTX_new(void);
动态分配一个摘要上下文(digest context)所需的内存空间,并返回指向这个摘要上下文的指针。
void EVP_MD_CTX_free(EVP_MD_CTX *ctx);
清理参数 ctx 指向的摘要上下文内存空间,然后释放这一段内存。
int EVP_MD_CTX_reset(EVP_MD_CTX *ctx);
重置参数 ctx 指向的摘要上下文,用户可以使用本函数来重用一个已经创建的摘要上下文,而不是再创建一个新的摘要上下文。
int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
使用摘要类型参数 type、引擎参数 impl 初始化摘要上下文参数 ctx 。参数 type 的值可以是以下函数的返回值:EVP_sha256( ), EVP_sha384( ),EVP_sha512( ),EVP_sm3( )等。当参数 impl 的值为 NULL 时,使用默认的引擎计算摘要值。
int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
与 EVP_DigestInit_ex( ) 类似,但总是使用默认的引擎计算摘要值。
int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt);
针对参数 d 指向的输入缓冲区中长度为 cnt 字节的数据计算摘要值。当原始数据长度较长、难以被一次性的读入内存缓冲区时,可以将数据分批读入缓冲区,反复调用该函数来计算摘要值,在这种情况下,每次调用该函数时参数 ctx 的值必须相同。
int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s);
从参数 ctx 中获取摘要值,放入参数 md 指向的缓冲区。如果参数 s 的值不是空指针,将摘要的长度赋值给指针 s 指向的整型变量。对于标准的摘要算法,其杂凑值长度是固定的,用户能够提前知道摘要值长度,不需要通过调用 EVP_DigestFinal_ex( ) 获取杂凑值长度,此时可以将变量 s 的值直接赋为 NULL,但是一定要保证用来存放摘要值的缓冲区长度足够容纳。调用 EVP_DigestFinal_ex( ) 函数将终结摘要计算过程,在此之后不能再调用 EVP_DigestUpdate( ) 函数。
EVP_DigestFinal_ex( ) 函数的实现在 \crypto\evp\digest.c 中,内部包含以下语句:
if (size != NULL)
*size = ctx->digest->md_size;
int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s);
与 EVP_DigestFinal_ex( ) 类似,并且该函数会重置 ctx 指向的摘要上下文。
该函数的实现在 \crypto\evp\digest.c 中,如下:
int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
{
int ret;
ret = EVP_DigestFinal_ex(ctx, md, size);
EVP_MD_CTX_reset(ctx);
return ret;
}
int EVP_MD_type(const EVP_MD *md);
当输入参数是一个 EVP_MD 结构体时,返回该摘要算法对象识别符对应的 NID。例如:EVP_MD_type(EVP_sha1()) 的返回值是 NID_sha1 。
如果根据输入的 EVP_MD 找不到对应的摘要算法,将返回 NID_undef 。
注意:
NID_sha1, NID_undef 都是在 \include\openssl\obj_mac.h 中定义的宏,常见的一些 NID 定义如下:
#define NID_undef 0
#define NID_sha1 64
#define NID_sha256 672
#define NID_sha256WithRSAEncryption 668
#define NID_sm3 1143
const EVP_MD *EVP_get_digestbynid(int type);
当输入值是一个摘要 NID 时,例如 NID_sha1,返回一个 EVP_MD 结构体。如果根据摘要 NID 找不到对应的摘要算法,将返回 NULL。
注意:
从 OpenSSL 1.1.0 版开始,以前版本中的 EVP_MD_CTX_create( ) 被重命名为 EVP_MD_CTX_new,EVP_MD_CTX_init( ) 被重命名为 EVP_MD_CTX_reset( ),EVP_MD_CTX_destroy( ) 被重命名为 EVP_MD_CTX_free( )。
在 OpenSSL 1.1.1 版的 \include\openssl\evp.h 文件中,可以看到以下宏定义:
# define EVP_MD_CTX_create() EVP_MD_CTX_new()
# define EVP_MD_CTX_init(ctx) EVP_MD_CTX_reset((ctx))
# define EVP_MD_CTX_destroy(ctx) EVP_MD_CTX_free((ctx))
OpenSSL 中的 EVP_MD 学习笔记(针对1.1.1版本)相关推荐
- Python中索引的学习笔记
1 前言 今天在学习FaceBoxes- 看到一个比较奇怪的代码,"order = scores.argsort()[::-1][:args.top_k]",不太懂这个" ...
- 机器人学中的状态估计——学习笔记
机器人学中的状态估计--学习笔记 离散时间的批量估计问题 1.最大后验概率法(Maximum A Posteriori, MAP) 2.贝叶斯推断(Bayesian inference) 离散时间的迭 ...
- 机器人学中的状态估计学习笔记(二)第三章线性高斯系统的状态估计
机器人学中的状态估计学习笔记(二)第三章线性高斯系统的状态估计 3.1 离散时间的批量估计问题 3.1.1 问题定义 3.1.2 最大后验估计 3.1.3 贝叶斯推断 3.1.4 存在性.唯一性与能观 ...
- java学习笔记:全部,txt版本
java学习笔记:全部,txt版本 笔者注: 1.不知道怎么上传附件,所以就把txt文本内容全部贴在这里吧. 2.已经把txt版本的笔记上传到CSDN了,我没有设置索要积分才能下载,但是不知道为什么C ...
- 英伟达DeepStream学习笔记27——deepstream下载历史版本
英伟达DeepStream学习笔记27--deepstream下载历史版本 https://docs.nvidia.com/metropolis/deepstream-archive.html htt ...
- 我的Android进阶之旅------gt;Android中编解码学习笔记
编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等 ...
- zynq中interrupts的学习笔记(一)
本学习笔记参考UG585-Zynq-7000-TRM.pdf ch.7:Interrupts.文中有说的不够严谨或者是有错误的地方,欢迎指正! zynq中的interrupts有很多种,大体上分为三类 ...
- Java中expecial,RxJava 学习笔记 (一)
作者: 一字马胡 转载标志 [2017-12-13] 更新日志 日期 更新内容 备注 2017-12-13 RxJava学习笔记系列 系列笔记 (一) 2017-12-15 增加系列笔记(二) 201 ...
- JavaSE中Map框架学习笔记
前言:最近几天都在生病,退烧之后身体虚弱.头疼.在床上躺了几天,什么事情都干不了.接下来这段时间,要好好加快进度才好. 前面用了三篇文章的篇幅学习了Collection框架的相关内容,而Map框架相对 ...
最新文章
- SQL server数据库日志满了怎么处理?
- 【软件】chrome设置默认字体
- PHP的JSON封装
- python骂人的程序_Python实现敏感词过滤的4种方法
- 8个使用JavaScript展示图片解决方案
- 程序员过关斩将--应对高并发系统有没有通用的解决方案呢?
- NCRE四级网络工程师考题详解----目录分解法
- pandownload限速原因及解决方案
- 华三服务器管理口地址_不同型号服务器的默认管理IP及账号密码汇总
- How to Create Your Own HDR Environment Maps
- MySQL索引原理以及查询优化
- 计算机辅助审计笔记,审计笔记2.0 盘点
- 联想惠普谁才是pc的最后王者
- [机器学习]决策树选西瓜
- redis学习之redis的发布和订阅
- 淘宝HTML5版私钥泄漏
- html5script计时器,javascript实现秒表计时器的制作方法
- 某宝 小黑屋 x-sg?xt x-si?n x-m?ni-w?a 分析学习
- 华为云GaussDB(for Redis)GaussDB(for Redis)全面对比Codis
- 玩转Google开源C++单元测试框架