openssl3.2 - 官方demo学习 - 索引贴
概述
如果要将openssl在自己的业务逻辑中用起来, 只从网上找零星的代码片段肯定不行的.
且不说人家写的好不好, 主要是我们不知道人家为啥那么写.
openSSL的API, 不同版本, API调用名称, 调用顺序. 是否为已经废弃, 都不同.
如果不是官方demo中推荐的写法, 如果有问题, 那也不好找问题. 作为研发, 我们比对能力还是强的.
如果是从网上找的代码片段, 在最新的openSS中是否能编译过, 都是个问题.
如果要用某个版本的openSSL(如果是新工程, 最好用新版的openSSL) , 看看官方提供的demo, 都清楚了.
如果是旧工程, 就要找对应的openSSL的版本的官方demo来看.
如果是从已有工程的旧openSSL版本迁移到最新的openSSL版本, 官方也有文档说明.
官方提供的Demo, 知识点比较全, 人家就是给用户写的很多具体例子(每个demo集中展示一个或几个小知识点), 用代码来展示openSSL库某个具体知识点具体咋用.
想将openssl3.2的官方demo过一遍, 过完之后, 就知道openssl能具体干啥了. 应用openssl库的编程细节也就知道了.
要想知道openssl3.2的编程细节, 看官方demo是最直接的方法.
在走读openssl demo实现时, 哪里有疑问, 可以自己写测试代码, 自己试试. 有自己的理解, 可以写注释给以后看.
当然, 在用openSSL干活之前, 密码学的书和资料也要稍微看看. 要不就不知道官方demo的知识背景.
如果能找到大佬出的教程, 初步看一下, 被大佬带一下, 让师傅领进门是最好的.
能出书和出教程的大佬, 人家也是看官方demo, 自己学出来的.
openSSL官方的demo都是在一个.c中实现的, 数了一下, 大概70个.
准备将这70个demo的源码走读完, 预计花7天.
等全部走读完, 业务逻辑上用到哪些openSSL操作, 就知道去哪个demo中找了.
移植(迁移)代码这事, 作为研发都熟悉, 不是问题.
笔记
工程的搭建和调试环境
VS2019 vc++ console
openSSL3.2安装到了c:\openssl_3d2
建立一个vs2019 c++ 控制台工程.
包含openssl3.2的头文件路径 => .;C:\openssl_3d2\include;
包含openssl3.2的库路径 => C:\openssl_3d2\lib;
删掉工程模板的.cpp实现
将官方实现(e.g. client-arg.c)放到工程中, 作为主实现
在.c中, 将库包含上, 将openssl/applink.c包进去.
#pragma comment(lib, "libcrypto.lib")
#pragma comment(lib, "libssl.lib")
#include <openssl/applink.c> /*! for OPENSSL_Uplink(00007FF8B7EF0FE8,08): no OPENSSL_Applink */
根据编译选项, 加入一些编译宏, 使程序0错误0警告.
add _CRT_SECURE_NO_WARNINGS to VS2019 option
此时编译工程, 就是能编译过的. 0错误0警告
然后就是自己单步看看程序功能和API用法.
在这个过程中, 看看此demo包含哪些知识点?
这些知识点的API的建立, 调用, 释放的流程?
这3步中, 参数都是咋给定的?
自己能从这个demo中学到啥? 如果有, 可以加个注释以后看.
是不是自己也可以尝试改2句试试?
如果此demo要和其他demo配合用, 等过到相关demo时, 再打开这个demo配合用一下, 能更好的理解demo的实现.
BIO
BIO是openssl处理输入/输出的API, 可以处理文件, SSL连接的读写.
BIO - client-arg.c
TLS客户端(服务器连接串从命令行参数来), 向服务器get一个东西
openssl3.2 - 官方demo学习 - client-arg.c
BIO - client-conf.c
TLS客户端(服务器连接串从配置文件来), 向服务器get一个东西
openssl3.2 - 官方demo学习 - client-conf.c
BIO - saccept.c
建立TLSServer(使用了证书, 和证书中的私钥), 接收客户端的连接, 并将客户端发来的信息打印到屏幕
openssl3.2 - 官方demo学习 - saccept.c
BIO - sconnect.c
TLS客户端 - 使用根证书, 非阻塞, 向服务器要东西.
openssl3.2 - 官方demo学习 - saccept.c
BIO - server-arg.c
TLS服务器, 等客户端来连接; 如果客户端断开了, 通过释放bio来释放客户端socket, 然后继续通过bio读来aceept.
openssl3.2 - 官方demo学习 - server-arg.c
BIO - server-cmod.c
从配置文件中读参数, 建立TLS服务器, 死等客户端来连接. 客户端连接后, 打印客户端发来的内容.
配置文件格式有要求
openssl3.2 - 官方demo学习 - server-cmod.c
BIO - server-conf.c
建立TLS服务器, 参数从配置文件中来.通过SSL_CONF_CTX_set_flags()来决定读那些TLS参数
遍历配置文件, 通过SSL_CONF_cmd()来读取预期的配置项.
如果不是TLS直接用的参数(e.g. BIO), 自己从配置文件Item中赋值到变量.
openssl3.2 - 官方demo学习 - server-conf.c
BIO - 总结
官方BIOdemo工程就这7个.
可以看出, BIO主要是和TLS通讯相关的. 隐藏了socket操作, TLS两端通讯时, 直接用BIO读写.
BIO隐藏了数据读写2边的信息, 需要在BIO在建立和配置时, 才能知道具体操作的是文件, 内存还是socket.
certs
这个目录中没有c实现, 是官方展示如何使用openssl命令行来干活.
openssl3.2 - 官方demo学习 - certs
cipher
这个目录是算法调用的例子(e.g. 调用EVP接口进行对称加解密)
cipher - aesccm.c
AES-192-CCM
openssl3.2 - 官方demo学习 - cipher - aesccm.c
cipher - aesgcm.c
AES-256-GCM
在这个实验中验证了EVP_CIPHER_fetch()中算法名称字符串的来源定位.
每次看官方一个demo工程, 都能有收获, 这就很好了. 即使从一个demo中仅仅学到或者体会到一点新东西.
e.g. 因为是调用的EVP接口, 不同的加解密算法之间的应用, 差别不大(有时只是调用的算法名称字符串不同), 那么看不同的cipher, 除了第一个cipher demo, 其他的cipher demo工程, 收获就没那么大.
openssl3.2 - 官方demo学习 - cipher - aesgcm.c
cipher - aeskeywrap.c
AES-256-WRAP
经过实验 EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); 不是必须的.
openssl3.2 - 官方demo学习 - cipher - aeskeywrap.c
cipher - ariacbc.c
ARIA-256-CBC
EVP_EncryptInit_x()的区别
EVP_EncryptInit() 参数为ctx, cipher, key, iv
EVP_EncryptInit_ex2() 参数为 ctx, cipher, key, iv, params[]
EVP_EncryptInit_ex() 参数为 ctx, cipher, engine_imp, key, iv
看了参数就知道:
如果不给params[], 就调用EVP_EncryptInit()
如果给params[], 就调用EVP_EncryptInit_ex2()
如果给engine, 就调用EVP_EncryptInit_ex()
openssl3.2 - 官方demo学习 - cipher - ariacbc.c
cipher - 总结
openssl3.2共支持130种算法
官方给的demos数量比较少, 这说明官方的算法API接口封装的比较好, 换用不同算法, 大多数只要改一下算法名称字符串即可.
官方给的例子全部使用EVP接口, 而不是底层具体的算法接口, 这样换算法时,非常方便.
取算法指针时, 都使用EVP_CIPHER_fetch(). 说明这是官方推荐的方法.
加解密流程(以加密为例):
EVP_CIPHER_CTX_new() 建立算法上下文.
EVP_CIPHER_fetch() 选择算法.
EVP_EncryptInit()/EVP_EncryptInit_ex2()/EVP_EncryptInit_ex() 算法初始化(给定key, iv, …)
EVP_EncryptUpdate() 连续加密buffer
EVP_EncryptFinal_ex() 加密结束
EVP_CIPHER_free() 释放算法
EVP_CIPHER_CTX_free() 释放算法上下文
cms
CMS is Cryptographic Message Syntax (CMS) standard
cms - cms_comp.c
用CMS操作, 将明文压缩
openssl3.2 - 官方demo学习 - cms - cms_comp.c
cms - cms_uncomp.c(官方应用实现错误, 需要修正)
cms数据解压缩
请注意函数定义 CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, unsigned int flags)
参数3才是输出的BIO
openssl3.2 - 官方demo学习 - cms - cms_uncomp.c(官方应用实现错误, 需要修正)
cms - cms_enc.c
用证书对明文进行CMS加密
CMS操作过的最终内容(除了反操作(解压缩, 解密))都是可见字符(数据用base64过了一遍).
openssl3.2 - 官方demo学习 - cms - cms_enc.c
cms - cms_dec.c
对用证书加密的CMS数据进行解密(也需要加密时用的那个证书)
openssl3.2 - 官方demo学习 - cms - cms_dec.c
cms - cms_denc.c
将CMS数据结构写入PEM文件, 并将分离后的加密数据单独写到数据文件.
cms - cms_denc.c
cms - cms_sign.c
CMS消息签名
openssl3.2 - 官方demo学习 - cms - cms_sign.c
cms - cms_sign2.c
用多个证书进行CMS消息联合签名
openssl3.2 - 官方demo学习 - cms - cms_sign2.c
cms - cms_ver.c
CMS验签, 将单独签名和联合签名出来的签名文件都试试.
验签成功后, 将签名数据明文写入了文件供查看.
也就是说, 只有验签成功后, 才能看到签名数据的明文.
验签时, 使用的是上一级的证书(这里是CA证书)
签名时, 使用的是低级证书(接收者证书, 或者说是签名者证书, 这些证书都是CA证书发出来的)
不管是单独签名, 还是联合签名, 验签都是一个API搞定.
openssl3.2 - 官方demo学习 - cms - cms_ver.c
cms总结
验签后, 可以得到签名前的签名数据明文.
对于CMS, 可以进行数据的压缩/解压缩, 加密/解密, 签名/验签.
可以将CMS数据结构和CMS实际数据分离开保存.
digest
摘要算法相关
digest - BIO_f_md.c
计算buffer的摘要(例子中使用的摘要算法为 SHA3-512)
openssl3.2 - 官方demo学习 - digest - BIO_f_md.c
digest - EVP_MD_xof.c
使用支持XOF方式的摘要算法(e.g. SHAKE256), 对buffer进行摘要, 并和预留的摘要值进行比对
openssl3.2 - 官方demo学习 - digest - EVP_MD_xof.c
digest - EVP_MD_stdin.c
使用 SHA3-512 对stdin输入做摘要, 并输出摘要值.
openssl3.2 - 官方demo学习 - digest - EVP_MD_stdin.c
digest - EVP_MD_demo.c
使用 SHA3-512 对多个buffer连续进行摘要, 最后得到一个摘要值
openssl3.2 - 官方demo学习 - digest - EVP_MD_demo.c
digest - 总结
这4个demo区别不明显, 熟悉一下做摘要的API调用流程. 看眼熟了就好.
encode
这里面一共2个demo, 看名称是rsa编码和ecc编码.
@todo 可是试了rsa_encode.c, 应该是官方程序逻辑有问题, 需要在屏幕上输入东西, 程序逻辑运行不下去.
没学到东西.
encode - rsa_encode.c
命令行参数 server_priv_key.pem client_priv_key.pem
这2个证书是前面certs目录里面做的
官方这个程序有bug, 给出2个证书, 还要从屏幕上输入
if (OSSL_DECODER_from_fp(dctx, f) == 0) { /*< 在这里阻塞住了, 让在屏幕上输入东西, 让我输入啥啊 ?
关键是输入了, 回车也不返回程序.
@todo 先放这里, 等整明白了, 再来修正这个工程.
openssl3.2 - 官方demo学习 - encode - rsa_encode.c
encode - ec_encode.c
@todo 一样有bug,
if (OSSL_DECODER_from_fp(dctx, f) == 0) { 阻塞住了, 不知道在屏幕上该输入些啥? 才行让程序往后走…
先放着, 等有头绪再来学习.
encode - 总结
@todo 没学到东西, 不知道官方2个工程要啥活?
作为库的使用者, 官方工程要能run才能看明白功能啊.
估计是这些demo没啥人学, 否则也不会有这些含有库应用bug的工程在这里摆着.
encrypt
这个目录就一个demo, 演示了从DER证书中得到公钥/私钥, 进行buffer的加解密
encrypt - rsa_encrypt.c
从内存中的DER共钥数据构造pub_key, 用公钥加密明文, 输出密文. 非对称加密
从内存中的DER私钥数据构造priv_key, 用私钥解密密文, 输出明文, 非对称解密
使用的哪种非堆成加解密算法是生成证书中指定的.
在从DER证书中构造key时, 也要指定RSA参数.
在加解密初始化, 要设置RSA相关参数
加解密之前, 都有API可以从要操作的数据长度估算出操作后的数据长度
这个例子演示了从内存中拿数据来进行非对称加解密, 避免了公钥/私钥数据落地
openssl3.2 - 官方demo学习 - encrypt - rsa_encrypt.c
guide
quic和tls客户端的例子
guide - quic-client-block.c
在程序运行时, 要指定环境变量 SSL_CERT_FILE=rootcert.pem, 同时将rootcert.pem拷贝到工程目录下, 否则不好使
吐槽啊, 为啥不用命令行参数或者API参数传进来啊, 整啥环境变量啊, 看着膈应.
quic服务启动(openssl3.2 - quic服务的运行)时的命令行为 quicserver.exe -trace localhost 23456 servercert.pem serverkey.pem
本程序(quic客户端)命令行只能为 localhost 23456 才行
用 127.0.0.1 23456 不好使.
如果要单步调试, 得赶紧的. quic服务启动后, 如果30秒内没有客户端来, quic服务会退出, 这太不礼貌了…
只能跑一下, 听个响, 学不到东西.
这个demo, 是不是只想展示, openssl可以作为quic客户端程序的tls实现?
openssl3.2 - 官方demo学习 - guide - quic-client-block.c
guide - quic - client-non-block.c
quic客户端非阻塞通讯的版本.
因为不能愉快的调试, 没学到东西.
只能编译运行一下, 听个响.
guide - quic - quic-multi-stream.c
连接一个quic服务器, 在一个SSL连接上, 开2个流进行通讯.
只是看了一下, 无法愉快调试.
guide - tls-client-block.c
@todo tls客户端程序, 编译完成, 配好命令行不能正常运行. 客户端无法正常连接服务端.
以后有头绪了再来实验.
openssl3.2 - 官方demo学习 - guide - tls-client-block.c
guide - tls-client-non-block.c
tls客户端程序.
@todo 报错情况和client-block.c一样, 等以后再解决
http3
@todo nghttp3在win10x64 + VS2019X64下编译失败, 放弃治疗
kdf
kdf - argon2.c
设置KDF算法的参数, 并获得key
openssl3.2 - 官方demo学习 - kdf - argon2.c
kdf - hkdf.c
设置摘要算法HKDF的参数, 然后取key
openssl3.2 - 官方demo学习 - kdf - hkdf.c
kdf - pbkdf2.c
设置PBKDF2算法的参数, 取key
openssl3.2 - 官方demo学习 - kdf - pbkdf2.c
kdf - scrypt.c
设置 kdf-SCRYPT算法的参数, 取key
openssl3.2 - 官方demo学习 - kdf - scrypt.c
kdf总结
官方这4个例子, 都是取key. 然后呢?
拿到kdf算法的key后, 咋用啊?
只能后续看看openssl.exe中哪个参数能执行到kdf算法相关的实现.
keyexch
keyexch目录就一个工程, 演示公钥的交换. 然后用对方公钥和自己私钥生成绘话密钥.
keyexch - x25519.c
官方程序中演示了私钥2种key交换的情况:
产生X25519的key对(私钥/公钥), 并交换公钥给对方, 并分别产生会话密钥, 使双方都能持有相同的会话密钥
产生X25519的key对(私钥/公钥)时, 产生私钥时, 可以随机产生. 这个私钥是为会话准备的, 然后根据会话私钥产生会话公钥.
然后交换公钥给对方, 并分别产生会话密钥, 使双方都能持有相同的会话密钥
可以看到case2更安全, 密钥不在程序中定义.
openssl3.2 - 官方demo学习 - keyexch - x25519.c
mac
mac - cmac-aes256.c
指定加密算法(e.g. AES-256-CBC), 对明文生成MAC数据
openssl3.2 - 官方demo学习 - mac - cmac-aes256.c
mac - gmac.c
使用GMAC算法, 设置参数(指定加密算法 e.g. AES-128-GCM, 设置iv)
用key执行初始化, 然后对明文生成MAC数据
官方注释给出建议, key, iv最好不要硬编码出现在程序中
openssl3.2 - 官方demo学习 - mac - gmac.c
mac - hmac-sha512.c
MAC算法为HMAC, 设置参数(摘要算法为SHA3-512), 用key初始化, 对明文做MAC数据.
openssl3.2 - 官方demo学习 - mac - hmac-sha512.c
mac - poly1305.c
MAC算法为Poly1305,
加密算法为AES-128-ECB, 用key初始化加密算法
加密算法进行padding填充
对加密算法的key加密, 放入MAC_key后16字节, 将MAC_key的前16字节清空, 作为要用的MAC_key
拿MAC_key来初始化MAC上下文
对明文进行MAC操作.
官方建议:
Poly1305不能单独使用, 必须和其他加密算法一起对输入(MAC_key)进行处理
绝对禁止将nonce(MAC_key)直接传给Poly1305
不同会话的nonce(MAC_key)禁止重用(相同).
在实际应用绝对禁止将nonce(MAC_key)硬编码
看来nonce对于Poly1305应用的安全性影响很大(知道了MAC_key, 就可以伪造MAC值)
openssl3.2 - 官方demo学习 - mac - poly1305.c
mac - siphash.c
MAC算法为 SIPHASH, 设置参数(C-rounds, D-rounds, 也可以不设置, 有默认值)
用key初始化MAC算法, 算明文的MAC值
openssl3.2 - 官方demo学习 - mac - siphash.c
mac - 总结
官方例子中给出了安全建议, 要重视.
pkcs12
这个目录中有2个demo, 都是要操作pkcs12证书.
但是官方certs目录中的脚本, 并没有生成pkcs12证书的操作.
@todo 只能先放着, 后续差资料, 先将pkcs12证书先做了, 再来做这个目录下的实验
pkcs12 - pkread.c
@todo
pkcs12 - pkwrite.c
@todo
test_certs
在openssl3.2目录下, 有个目录.\test\certs, 里面有官方测试用的2个脚本 : mkcert.sh, setup.sh
只能在cygwin64下运行.
运行setup.sh, 间接调用mkcert.sh, 产生并测试了所有类型的证书(包括pkcs12格式的证书)
这2个.sh比.\demos\certs目录下的演示用.sh强太多了.
但是这2个.sh是纯bash脚本, 得做实验, 将具体的命令行取出来, 才能看清楚每个证书操作的命令行.
@todo 等后续来弄, 如果将这2个脚本弄明白, 那就是最全的证书命令行操作了.
pkey
pkey - EVP_PKEY_DSA_keygen.c
das.h 中有2个公共函数(给pkey目录的所有工程公用):
print_bn() 打印大数值
dsa_print_key() 打印key值
打印_evp_pkey_dsa的共有数据(p,q,g, seed, pcounter) + 公钥/私钥 + DSA参数
每次产生的pkey都不一样(因为seed不一样)
openssl3.2 - 官方demo学习 - pkey - EVP_PKEY_DSA_keygen.c
pkey - EVP_PKEY_DSA_paramfromdata.c
开源工程包含的头文件类型是.inc, 要重命名为.h, 否则没有c++头文件语法提示
从数组中载入大数p,q,g
建立ossl_param, 设置参数的p,q,g
用参数初始化_evp_pkey_ctx, 得到_evp_pkey_dsa
打印_evp_pkey_dsa的共有数据(p,q,g …) + 参数
openssl3.2 - 官方demo学习 - pkey - EVP_PKEY_DSA_paramfromdata.c
pkey - EVP_PKEY_DSA_paramgen.c
产生DSA的_evp_pkey_ctx
初始化_evp_pkey_ctx
设置参数到_evp_pkey_ctx
由_evp_pkey_ctx产生_evp_pkey
打印_evp_pkey公开值和DSA param
openssl3.2 - 官方demo学习 - pkey - EVP_PKEY_DSA_paramgen.c
pkey - EVP_PKEY_DSA_paramvalidate.c
OPENSSL_hexstr2buf_ex 将16禁止字符串填充到16进制buffer
BIO_new_mem_buf 有用, 可以内存的内容转为bio, 不用非要落地为文件才能操作
将buffer中写的DSA param 载入到bio
从bio产生_evp_pkey_dsa
从 pkey产生 _evp_pkey_ctx1, 检查 _evp_pkey_ctx1的param
设置新的param, 和 _evp_pkey_dsa 一起, 产生新的_evp_pkey_ctx2, 检查 _evp_pkey_ctx2的param
再次设置一个新的param, 用OSSL_PARAM_merge合并_evp_pkey_ctx2的param, 作为新的param
用新的param产生新的ctx => _evp_pkey_ctx3, 检查 _evp_pkey_ctx3的参数
取 _evp_pkey_ctx3的EVP_PKEY, 并打印EVP_PKEY的公用参数和param
openssl3.2 - 官方demo学习 - pkey - EVP_PKEY_DSA_paramvalidate.c
pkey - EVP_PKEY_EC_keygen.c
给定椭圆曲线名字, 产生上下文_evp_pkey_ctx
设置_evp_pkey_ctx的椭圆曲线参数(有默认参数, 不用特意设置, 给熟悉的人用), 不熟悉密码学的人, 只选椭圆曲线的名字就行
从_evp_pkey_ctx产生ec key;
打印 ec EVP_PKEY 的值(可以取出椭圆曲线的名字, 公钥, 私钥).
openssl3.2 - 官方demo学习 - pkey - EVP_PKEY_EC_keygen.c
pkey - EVP_PKEY_RSA_keygen.c
官方指出 : RSA key 如果小于2048位, 就属于弱key
官方demo中, 给出的默认key长度为4096位
从名字生成上下文
初始化上下文
设置上下的key位数
设置质数数量为2
产生RSA Key. (在我的本本上, 单步调试时, 感觉产生 RSA key时, 卡了一下, 大概不到1秒钟)
打印rsa key内容(可以得到 n, e, d, p, q, key的位数, 公钥, 私钥)
PEM_write_x时, 如果文件句柄是具体的文件, 就是将公钥/密钥保存成了PEM文件.
openssl3.2 - 官方demo学习 - pkey - EVP_PKEY_RSA_keygen.c
signature
signature - rsa_pss_direct.c
用RSA私钥签名
d2i_PrivateKey_ex()可以从内存载入私钥数据, 得到私钥EVP_PKEY*
从私钥产生ctx, 对ctx进行签名初始化, 设置ctx的padding填充模式
摘要算法选用SHA256, 对ctx设置摘要算法
尝试签名, 得到签名长度, 然后进行私钥签名, 得到私钥签名buffer.
用RSA公钥验签
d2i_PublicKey()可以从内存载入公钥数据, 得到公钥EVP_PKEY*
验签时使用的摘要算法要和签名时一样.
验签初始化, 对ctx进行验签初始化, 这是ctx的padding填充模式(要和签名时一样)
进行验签
openssl3.2 - 官方demo学习 - signature - rsa_pss_direct.c
signature - rsa_pss_hash.c
对私钥对明文做签名(摘要算法为SHA256)
用公钥对密文做验签(摘要算法为SHA256)
openssl3.2 - 官方demo学习 - signature - rsa_pss_hash.c
signature - EVP_DSA_Signature_demo.c
DSA签名(摘要算法SHA256), DSA验签(摘要算法SHA256)
签名 : 用发送者的私钥进行签名.
验签 : 用发送者的公钥进行验签.
看下API调用顺序就行, 自己弄的时候, 跟着demo的流程弄就行.
对于openssl3.2, 越看越眼熟了.
openssl3.2 - 官方demo学习 - signature - EVP_DSA_Signature_demo.c
signature - EVP_ED_Signature_demo.c
ED25519 签名/验签算法, 现在是最好的.
产生ED25519私钥/公钥
用私钥对明文签名, 得到签名数据
用公钥对明文和签名数据进行验签
openssl3.2 - 官方demo学习 - signature - EVP_ED_Signature_demo.c
signature - EVP_EC_Signature_demo.c
EC的签名/验签实现, 摘要算法为 SHA3-512
签名验签时的update铭文可以进行多次.
openssl的API封装的真好, 只要是一类流程(e.g. 签名/验签), 采用不同算法时, 差别不大.
以前看资料, 那个老师说, 最好不要用名字来取算法指针, 容易写错. 而且调用的API比较麻烦.
已经单步调试了几十个官方demo, 官方全部采用名称字符串来取东西.
说明, 用名字取东西, 才可以让同一类操作的维护性最好.
看了一眼openSSL的底层用名字取东西的实现, 人家是做了一个Map, Map的成员是一个结构指针, 里面有名字和任务指针.
没仔细看, Map的Key应该是个hash值, 效率肯定刚刚的.
至于名称字符串容易写错, 自己准备一个用名字取东西的API的名字有效值的文档就可以搞定这个问题.
openssl3.2 - 官方demo学习 - signature - EVP_EC_Signature_demo.c
smime
smime - smenc.c
读取X509证书, 用PKCS7加密明文(证书 + 明文 + 3DES_CBC), 保存为MIME格式的密文
openssl API的命名含义
BIO_new_file
“new” a “file”, return a “BIO” object
PEM_read_bio_X509() Read a certificate in PEM format from a BIO
data format is “PEM”, “read” from “bio”, return a object type is “X509”
openssl3.2 - 官方demo学习 - smime - smenc.c
smime - smdec.c
从pem证书中得到x509*和私钥, 用私钥和证书解密MIME格式的PKCS7密文, 并保存解密后的明文
MIME的数据操作, 都是PKCS7相关的
openssl3.2 - 官方demo学习 - smime - smdec.c
smime - smsign.c
从证书中得到X509*和私钥指针
用证书和私钥对铭文进行签名, 得到签名后的pkcs7指针
将pkcs7指向的bio_in, 写为MIME格式的签名密文
BIO_reset() 可以将一个bio恢复到刚打开的状态(应该就是将文件指针重新指向文件头部), 一般用于只读打开的场景
经常用于多个对象要操作同一个bio的场景(一先一后的操作).
openssl3.2 - 官方demo学习 - smime - smsign.c
smime - smsign2.c
PKCS7联合签名
从N张证书中, 分别得到N对(x509和私钥)
对明文进行签名(只是指定了bio_in和flag), 得到pkcs7*
对此pkcs7进行附加签名者的操作(指定证书和私钥), 有几个联合签名者, 就进行几次操作
将签名数据pkcs7写为密文
openssl3.2 - 官方demo学习 - smime - smsign2.c
smime - smver.c
对于签名文件(不管是单独签名, 还是联合签名), 都要用顶层证书进行验签(靠近根CA的证书)
读证书文件, 得到x509*, 添加到证书容器
读取签名密文, 得到pkcs7*和密文的bio
进行pkcs7验签, 并将验签得到的签名的明文写到文件.
openssl3.2 - 官方demo学习 - smime - smver.c
sslecho - main.c
简单的echo TLS客户端和服务器, 都在一个工程中, 用命令行参数来区分客户端和服务器逻辑.
里面包含了linux的头文件, 编译不过. 等有时间再改为windows工程试试效果.
工程中有个很重要的提示文档 A-SSL-Docs.txt
Useful Links:
OpenSSL API Documentation: https://www.openssl.org/docs
Github: https://github.com/openssl/openssl
OpenSSL Wiki: https://wiki.openssl.org/index.php/Main_Page
Original Simple Server: https://wiki.openssl.org/index.php/Simple_TLS_Server
---------------------------------------------------------------
Generate self signed cert and key 'pem' files (good for 10 years):
openssl req -newkey rsa:4096 -x509 -sha256 -days 3650 -nodes -out cert.pem -keyout key.pem
You can just hit carriage returns to accept the default values, except for "Common Name"; you
should enter 'localhost', or an actual hostname.
The same keys can be used for both communicating instances; same or different machines.
官方博客说的openssl3.2的手册指南url
file:///C:/openssl_3d2/html/man7/ossl-guide-introduction.html
官方推荐的书
<> => https://www.feistyduck.com/library/openssl-cookbook/online/
第三方编译好的openssl版本
https://slproweb.com/products/Win32OpenSSL.html文章来源:https://www.toymoban.com/news/detail-788321.html
单独使用自己编译的openssl命令行时的批处理文件
@echo off
rem \file my_openssl_env_cmd.cmd
set OPENSSL=.\openssl
set OPENSSL_CONF=.\openssl.cnf
cmd
openssl命令行整理
openssl命令行整理文章来源地址https://www.toymoban.com/news/detail-788321.html
END
到了这里,关于openssl3.2 - 官方demo学习 - 索引贴的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!