openssl3.2 - 官方demo學(xué)習(xí) - 索引貼
概述
如果要將openssl在自己的業(yè)務(wù)邏輯中用起來, 只從網(wǎng)上找零星的代碼片段肯定不行的.
且不說人家寫的好不好, 主要是我們不知道人家為啥那么寫.
openSSL的API, 不同版本, API調(diào)用名稱, 調(diào)用順序. 是否為已經(jīng)廢棄, 都不同.
如果不是官方demo中推薦的寫法, 如果有問題, 那也不好找問題. 作為研發(fā), 我們比對能力還是強的.
如果是從網(wǎng)上找的代碼片段, 在最新的openSS中是否能編譯過, 都是個問題.
如果要用某個版本的openSSL(如果是新工程, 最好用新版的openSSL) , 看看官方提供的demo, 都清楚了.
如果是舊工程, 就要找對應(yīng)的openSSL的版本的官方demo來看.
如果是從已有工程的舊openSSL版本遷移到最新的openSSL版本, 官方也有文檔說明.
官方提供的Demo, 知識點比較全, 人家就是給用戶寫的很多具體例子(每個demo集中展示一個或幾個小知識點), 用代碼來展示openSSL庫某個具體知識點具體咋用.
想將openssl3.2的官方demo過一遍, 過完之后, 就知道openssl能具體干啥了. 應(yīng)用openssl庫的編程細節(jié)也就知道了.
要想知道openssl3.2的編程細節(jié), 看官方demo是最直接的方法.
在走讀openssl demo實現(xiàn)時, 哪里有疑問, 可以自己寫測試代碼, 自己試試. 有自己的理解, 可以寫注釋給以后看.
當(dāng)然, 在用openSSL干活之前, 密碼學(xué)的書和資料也要稍微看看. 要不就不知道官方demo的知識背景.
如果能找到大佬出的教程, 初步看一下, 被大佬帶一下, 讓師傅領(lǐng)進門是最好的.
能出書和出教程的大佬, 人家也是看官方demo, 自己學(xué)出來的.
openSSL官方的demo都是在一個.c中實現(xiàn)的, 數(shù)了一下, 大概70個.
準(zhǔn)備將這70個demo的源碼走讀完, 預(yù)計花7天.
等全部走讀完, 業(yè)務(wù)邏輯上用到哪些openSSL操作, 就知道去哪個demo中找了.
移植(遷移)代碼這事, 作為研發(fā)都熟悉, 不是問題.
筆記
工程的搭建和調(diào)試環(huán)境
VS2019 vc++ console
openSSL3.2安裝到了c:\openssl_3d2
建立一個vs2019 c++ 控制臺工程.
包含openssl3.2的頭文件路徑 => .;C:\openssl_3d2\include;
包含openssl3.2的庫路徑 => C:\openssl_3d2\lib;
刪掉工程模板的.cpp實現(xiàn)
將官方實現(xiàn)(e.g. client-arg.c)放到工程中, 作為主實現(xiàn)
在.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 */
根據(jù)編譯選項, 加入一些編譯宏, 使程序0錯誤0警告.
add _CRT_SECURE_NO_WARNINGS to VS2019 option
此時編譯工程, 就是能編譯過的. 0錯誤0警告
然后就是自己單步看看程序功能和API用法.
在這個過程中, 看看此demo包含哪些知識點?
這些知識點的API的建立, 調(diào)用, 釋放的流程?
這3步中, 參數(shù)都是咋給定的?
自己能從這個demo中學(xué)到啥? 如果有, 可以加個注釋以后看.
是不是自己也可以嘗試改2句試試?
如果此demo要和其他demo配合用, 等過到相關(guān)demo時, 再打開這個demo配合用一下, 能更好的理解demo的實現(xiàn).
BIO
BIO是openssl處理輸入/輸出的API, 可以處理文件, SSL連接的讀寫.
BIO - client-arg.c
TLS客戶端(服務(wù)器連接串從命令行參數(shù)來), 向服務(wù)器get一個東西
openssl3.2 - 官方demo學(xué)習(xí) - client-arg.c
BIO - client-conf.c
TLS客戶端(服務(wù)器連接串從配置文件來), 向服務(wù)器get一個東西
openssl3.2 - 官方demo學(xué)習(xí) - client-conf.c
BIO - saccept.c
建立TLSServer(使用了證書, 和證書中的私鑰), 接收客戶端的連接, 并將客戶端發(fā)來的信息打印到屏幕
openssl3.2 - 官方demo學(xué)習(xí) - saccept.c
BIO - sconnect.c
TLS客戶端 - 使用根證書, 非阻塞, 向服務(wù)器要東西.
openssl3.2 - 官方demo學(xué)習(xí) - saccept.c
BIO - server-arg.c
TLS服務(wù)器, 等客戶端來連接; 如果客戶端斷開了, 通過釋放bio來釋放客戶端socket, 然后繼續(xù)通過bio讀來aceept.
openssl3.2 - 官方demo學(xué)習(xí) - server-arg.c
BIO - server-cmod.c
從配置文件中讀參數(shù), 建立TLS服務(wù)器, 死等客戶端來連接. 客戶端連接后, 打印客戶端發(fā)來的內(nèi)容.
配置文件格式有要求
openssl3.2 - 官方demo學(xué)習(xí) - server-cmod.c
BIO - server-conf.c
建立TLS服務(wù)器, 參數(shù)從配置文件中來.通過SSL_CONF_CTX_set_flags()來決定讀那些TLS參數(shù)
遍歷配置文件, 通過SSL_CONF_cmd()來讀取預(yù)期的配置項.
如果不是TLS直接用的參數(shù)(e.g. BIO), 自己從配置文件Item中賦值到變量.
openssl3.2 - 官方demo學(xué)習(xí) - server-conf.c
BIO - 總結(jié)
官方BIOdemo工程就這7個.
可以看出, BIO主要是和TLS通訊相關(guān)的. 隱藏了socket操作, TLS兩端通訊時, 直接用BIO讀寫.
BIO隱藏了數(shù)據(jù)讀寫2邊的信息, 需要在BIO在建立和配置時, 才能知道具體操作的是文件, 內(nèi)存還是socket.
certs
這個目錄中沒有c實現(xiàn), 是官方展示如何使用openssl命令行來干活.
openssl3.2 - 官方demo學(xué)習(xí) - certs
cipher
這個目錄是算法調(diào)用的例子(e.g. 調(diào)用EVP接口進行對稱加解密)
cipher - aesccm.c
AES-192-CCM
openssl3.2 - 官方demo學(xué)習(xí) - cipher - aesccm.c
cipher - aesgcm.c
AES-256-GCM
在這個實驗中驗證了EVP_CIPHER_fetch()中算法名稱字符串的來源定位.
每次看官方一個demo工程, 都能有收獲, 這就很好了. 即使從一個demo中僅僅學(xué)到或者體會到一點新東西.
e.g. 因為是調(diào)用的EVP接口, 不同的加解密算法之間的應(yīng)用, 差別不大(有時只是調(diào)用的算法名稱字符串不同), 那么看不同的cipher, 除了第一個cipher demo, 其他的cipher demo工程, 收獲就沒那么大.
openssl3.2 - 官方demo學(xué)習(xí) - cipher - aesgcm.c
cipher - aeskeywrap.c
AES-256-WRAP
經(jīng)過實驗 EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); 不是必須的.
openssl3.2 - 官方demo學(xué)習(xí) - cipher - aeskeywrap.c
cipher - ariacbc.c
ARIA-256-CBC
EVP_EncryptInit_x()的區(qū)別
EVP_EncryptInit() 參數(shù)為ctx, cipher, key, iv
EVP_EncryptInit_ex2() 參數(shù)為 ctx, cipher, key, iv, params[]
EVP_EncryptInit_ex() 參數(shù)為 ctx, cipher, engine_imp, key, iv
看了參數(shù)就知道:
如果不給params[], 就調(diào)用EVP_EncryptInit()
如果給params[], 就調(diào)用EVP_EncryptInit_ex2()
如果給engine, 就調(diào)用EVP_EncryptInit_ex()
openssl3.2 - 官方demo學(xué)習(xí) - cipher - ariacbc.c
cipher - 總結(jié)
openssl3.2共支持130種算法
官方給的demos數(shù)量比較少, 這說明官方的算法API接口封裝的比較好, 換用不同算法, 大多數(shù)只要改一下算法名稱字符串即可.
官方給的例子全部使用EVP接口, 而不是底層具體的算法接口, 這樣換算法時,非常方便.
取算法指針時, 都使用EVP_CIPHER_fetch(). 說明這是官方推薦的方法.
加解密流程(以加密為例):
EVP_CIPHER_CTX_new() 建立算法上下文.
EVP_CIPHER_fetch() 選擇算法.
EVP_EncryptInit()/EVP_EncryptInit_ex2()/EVP_EncryptInit_ex() 算法初始化(給定key, iv, …)
EVP_EncryptUpdate() 連續(xù)加密buffer
EVP_EncryptFinal_ex() 加密結(jié)束
EVP_CIPHER_free() 釋放算法
EVP_CIPHER_CTX_free() 釋放算法上下文
cms
CMS is Cryptographic Message Syntax (CMS) standard
cms - cms_comp.c
用CMS操作, 將明文壓縮
openssl3.2 - 官方demo學(xué)習(xí) - cms - cms_comp.c
cms - cms_uncomp.c(官方應(yīng)用實現(xiàn)錯誤, 需要修正)
cms數(shù)據(jù)解壓縮
請注意函數(shù)定義 CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, unsigned int flags)
參數(shù)3才是輸出的BIO
openssl3.2 - 官方demo學(xué)習(xí) - cms - cms_uncomp.c(官方應(yīng)用實現(xiàn)錯誤, 需要修正)
cms - cms_enc.c
用證書對明文進行CMS加密
CMS操作過的最終內(nèi)容(除了反操作(解壓縮, 解密))都是可見字符(數(shù)據(jù)用base64過了一遍).
openssl3.2 - 官方demo學(xué)習(xí) - cms - cms_enc.c
cms - cms_dec.c
對用證書加密的CMS數(shù)據(jù)進行解密(也需要加密時用的那個證書)
openssl3.2 - 官方demo學(xué)習(xí) - cms - cms_dec.c
cms - cms_denc.c
將CMS數(shù)據(jù)結(jié)構(gòu)寫入PEM文件, 并將分離后的加密數(shù)據(jù)單獨寫到數(shù)據(jù)文件.
cms - cms_denc.c
cms - cms_sign.c
CMS消息簽名
openssl3.2 - 官方demo學(xué)習(xí) - cms - cms_sign.c
cms - cms_sign2.c
用多個證書進行CMS消息聯(lián)合簽名
openssl3.2 - 官方demo學(xué)習(xí) - cms - cms_sign2.c
cms - cms_ver.c
CMS驗簽, 將單獨簽名和聯(lián)合簽名出來的簽名文件都試試.
驗簽成功后, 將簽名數(shù)據(jù)明文寫入了文件供查看.
也就是說, 只有驗簽成功后, 才能看到簽名數(shù)據(jù)的明文.
驗簽時, 使用的是上一級的證書(這里是CA證書)
簽名時, 使用的是低級證書(接收者證書, 或者說是簽名者證書, 這些證書都是CA證書發(fā)出來的)
不管是單獨簽名, 還是聯(lián)合簽名, 驗簽都是一個API搞定.
openssl3.2 - 官方demo學(xué)習(xí) - cms - cms_ver.c
cms總結(jié)
驗簽后, 可以得到簽名前的簽名數(shù)據(jù)明文.
對于CMS, 可以進行數(shù)據(jù)的壓縮/解壓縮, 加密/解密, 簽名/驗簽.
可以將CMS數(shù)據(jù)結(jié)構(gòu)和CMS實際數(shù)據(jù)分離開保存.
digest
摘要算法相關(guān)
digest - BIO_f_md.c
計算buffer的摘要(例子中使用的摘要算法為 SHA3-512)
openssl3.2 - 官方demo學(xué)習(xí) - digest - BIO_f_md.c
digest - EVP_MD_xof.c
使用支持XOF方式的摘要算法(e.g. SHAKE256), 對buffer進行摘要, 并和預(yù)留的摘要值進行比對
openssl3.2 - 官方demo學(xué)習(xí) - digest - EVP_MD_xof.c
digest - EVP_MD_stdin.c
使用 SHA3-512 對stdin輸入做摘要, 并輸出摘要值.
openssl3.2 - 官方demo學(xué)習(xí) - digest - EVP_MD_stdin.c
digest - EVP_MD_demo.c
使用 SHA3-512 對多個buffer連續(xù)進行摘要, 最后得到一個摘要值
openssl3.2 - 官方demo學(xué)習(xí) - digest - EVP_MD_demo.c
digest - 總結(jié)
這4個demo區(qū)別不明顯, 熟悉一下做摘要的API調(diào)用流程. 看眼熟了就好.
encode
這里面一共2個demo, 看名稱是rsa編碼和ecc編碼.
@todo 可是試了rsa_encode.c, 應(yīng)該是官方程序邏輯有問題, 需要在屏幕上輸入東西, 程序邏輯運行不下去.
沒學(xué)到東西.
encode - rsa_encode.c
命令行參數(shù) server_priv_key.pem client_priv_key.pem
這2個證書是前面certs目錄里面做的
官方這個程序有bug, 給出2個證書, 還要從屏幕上輸入
if (OSSL_DECODER_from_fp(dctx, f) == 0) { /*< 在這里阻塞住了, 讓在屏幕上輸入東西, 讓我輸入啥啊 ?
關(guān)鍵是輸入了, 回車也不返回程序.
@todo 先放這里, 等整明白了, 再來修正這個工程.
openssl3.2 - 官方demo學(xué)習(xí) - encode - rsa_encode.c
encode - ec_encode.c
@todo 一樣有bug,
if (OSSL_DECODER_from_fp(dctx, f) == 0) { 阻塞住了, 不知道在屏幕上該輸入些啥? 才行讓程序往后走…
先放著, 等有頭緒再來學(xué)習(xí).
encode - 總結(jié)
@todo 沒學(xué)到東西, 不知道官方2個工程要啥活?
作為庫的使用者, 官方工程要能run才能看明白功能啊.
估計是這些demo沒啥人學(xué), 否則也不會有這些含有庫應(yīng)用bug的工程在這里擺著.
encrypt
這個目錄就一個demo, 演示了從DER證書中得到公鑰/私鑰, 進行buffer的加解密
encrypt - rsa_encrypt.c
從內(nèi)存中的DER共鑰數(shù)據(jù)構(gòu)造pub_key, 用公鑰加密明文, 輸出密文. 非對稱加密
從內(nèi)存中的DER私鑰數(shù)據(jù)構(gòu)造priv_key, 用私鑰解密密文, 輸出明文, 非對稱解密
使用的哪種非堆成加解密算法是生成證書中指定的.
在從DER證書中構(gòu)造key時, 也要指定RSA參數(shù).
在加解密初始化, 要設(shè)置RSA相關(guān)參數(shù)
加解密之前, 都有API可以從要操作的數(shù)據(jù)長度估算出操作后的數(shù)據(jù)長度
這個例子演示了從內(nèi)存中拿數(shù)據(jù)來進行非對稱加解密, 避免了公鑰/私鑰數(shù)據(jù)落地
openssl3.2 - 官方demo學(xué)習(xí) - encrypt - rsa_encrypt.c
guide
quic和tls客戶端的例子
guide - quic-client-block.c
在程序運行時, 要指定環(huán)境變量 SSL_CERT_FILE=rootcert.pem, 同時將rootcert.pem拷貝到工程目錄下, 否則不好使
吐槽啊, 為啥不用命令行參數(shù)或者API參數(shù)傳進來啊, 整啥環(huán)境變量啊, 看著膈應(yīng).
quic服務(wù)啟動(openssl3.2 - quic服務(wù)的運行)時的命令行為 quicserver.exe -trace localhost 23456 servercert.pem serverkey.pem
本程序(quic客戶端)命令行只能為 localhost 23456 才行
用 127.0.0.1 23456 不好使.
如果要單步調(diào)試, 得趕緊的. quic服務(wù)啟動后, 如果30秒內(nèi)沒有客戶端來, quic服務(wù)會退出, 這太不禮貌了…
只能跑一下, 聽個響, 學(xué)不到東西.
這個demo, 是不是只想展示, openssl可以作為quic客戶端程序的tls實現(xiàn)?
openssl3.2 - 官方demo學(xué)習(xí) - guide - quic-client-block.c
guide - quic - client-non-block.c
quic客戶端非阻塞通訊的版本.
因為不能愉快的調(diào)試, 沒學(xué)到東西.
只能編譯運行一下, 聽個響.
guide - quic - quic-multi-stream.c
連接一個quic服務(wù)器, 在一個SSL連接上, 開2個流進行通訊.
只是看了一下, 無法愉快調(diào)試.
guide - tls-client-block.c
@todo tls客戶端程序, 編譯完成, 配好命令行不能正常運行. 客戶端無法正常連接服務(wù)端.
以后有頭緒了再來實驗.
openssl3.2 - 官方demo學(xué)習(xí) - 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
設(shè)置KDF算法的參數(shù), 并獲得key
openssl3.2 - 官方demo學(xué)習(xí) - kdf - argon2.c
kdf - hkdf.c
設(shè)置摘要算法HKDF的參數(shù), 然后取key
openssl3.2 - 官方demo學(xué)習(xí) - kdf - hkdf.c
kdf - pbkdf2.c
設(shè)置PBKDF2算法的參數(shù), 取key
openssl3.2 - 官方demo學(xué)習(xí) - kdf - pbkdf2.c
kdf - scrypt.c
設(shè)置 kdf-SCRYPT算法的參數(shù), 取key
openssl3.2 - 官方demo學(xué)習(xí) - kdf - scrypt.c
kdf總結(jié)
官方這4個例子, 都是取key. 然后呢?
拿到kdf算法的key后, 咋用啊?
只能后續(xù)看看openssl.exe中哪個參數(shù)能執(zhí)行到kdf算法相關(guān)的實現(xiàn).
keyexch
keyexch目錄就一個工程, 演示公鑰的交換. 然后用對方公鑰和自己私鑰生成繪話密鑰.
keyexch - x25519.c
官方程序中演示了私鑰2種key交換的情況:
產(chǎn)生X25519的key對(私鑰/公鑰), 并交換公鑰給對方, 并分別產(chǎn)生會話密鑰, 使雙方都能持有相同的會話密鑰
產(chǎn)生X25519的key對(私鑰/公鑰)時, 產(chǎn)生私鑰時, 可以隨機產(chǎn)生. 這個私鑰是為會話準(zhǔn)備的, 然后根據(jù)會話私鑰產(chǎn)生會話公鑰.
然后交換公鑰給對方, 并分別產(chǎn)生會話密鑰, 使雙方都能持有相同的會話密鑰
可以看到case2更安全, 密鑰不在程序中定義.
openssl3.2 - 官方demo學(xué)習(xí) - keyexch - x25519.c
mac
mac - cmac-aes256.c
指定加密算法(e.g. AES-256-CBC), 對明文生成MAC數(shù)據(jù)
openssl3.2 - 官方demo學(xué)習(xí) - mac - cmac-aes256.c
mac - gmac.c
使用GMAC算法, 設(shè)置參數(shù)(指定加密算法 e.g. AES-128-GCM, 設(shè)置iv)
用key執(zhí)行初始化, 然后對明文生成MAC數(shù)據(jù)
官方注釋給出建議, key, iv最好不要硬編碼出現(xiàn)在程序中
openssl3.2 - 官方demo學(xué)習(xí) - mac - gmac.c
mac - hmac-sha512.c
MAC算法為HMAC, 設(shè)置參數(shù)(摘要算法為SHA3-512), 用key初始化, 對明文做MAC數(shù)據(jù).
openssl3.2 - 官方demo學(xué)習(xí) - mac - hmac-sha512.c
mac - poly1305.c
MAC算法為Poly1305,
加密算法為AES-128-ECB, 用key初始化加密算法
加密算法進行padding填充
對加密算法的key加密, 放入MAC_key后16字節(jié), 將MAC_key的前16字節(jié)清空, 作為要用的MAC_key
拿MAC_key來初始化MAC上下文
對明文進行MAC操作.
官方建議:
Poly1305不能單獨使用, 必須和其他加密算法一起對輸入(MAC_key)進行處理
絕對禁止將nonce(MAC_key)直接傳給Poly1305
不同會話的nonce(MAC_key)禁止重用(相同).
在實際應(yīng)用絕對禁止將nonce(MAC_key)硬編碼
看來nonce對于Poly1305應(yīng)用的安全性影響很大(知道了MAC_key, 就可以偽造MAC值)
openssl3.2 - 官方demo學(xué)習(xí) - mac - poly1305.c
mac - siphash.c
MAC算法為 SIPHASH, 設(shè)置參數(shù)(C-rounds, D-rounds, 也可以不設(shè)置, 有默認(rèn)值)
用key初始化MAC算法, 算明文的MAC值
openssl3.2 - 官方demo學(xué)習(xí) - mac - siphash.c
mac - 總結(jié)
官方例子中給出了安全建議, 要重視.
pkcs12
這個目錄中有2個demo, 都是要操作pkcs12證書.
但是官方certs目錄中的腳本, 并沒有生成pkcs12證書的操作.
@todo 只能先放著, 后續(xù)差資料, 先將pkcs12證書先做了, 再來做這個目錄下的實驗
pkcs12 - pkread.c
@todo
pkcs12 - pkwrite.c
@todo
test_certs
在openssl3.2目錄下, 有個目錄.\test\certs, 里面有官方測試用的2個腳本 : mkcert.sh, setup.sh
只能在cygwin64下運行.
運行setup.sh, 間接調(diào)用mkcert.sh, 產(chǎn)生并測試了所有類型的證書(包括pkcs12格式的證書)
這2個.sh比.\demos\certs目錄下的演示用.sh強太多了.
但是這2個.sh是純bash腳本, 得做實驗, 將具體的命令行取出來, 才能看清楚每個證書操作的命令行.
@todo 等后續(xù)來弄, 如果將這2個腳本弄明白, 那就是最全的證書命令行操作了.
pkey
pkey - EVP_PKEY_DSA_keygen.c
das.h 中有2個公共函數(shù)(給pkey目錄的所有工程公用):
print_bn() 打印大數(shù)值
dsa_print_key() 打印key值
打印_evp_pkey_dsa的共有數(shù)據(jù)(p,q,g, seed, pcounter) + 公鑰/私鑰 + DSA參數(shù)
每次產(chǎn)生的pkey都不一樣(因為seed不一樣)
openssl3.2 - 官方demo學(xué)習(xí) - pkey - EVP_PKEY_DSA_keygen.c
pkey - EVP_PKEY_DSA_paramfromdata.c
開源工程包含的頭文件類型是.inc, 要重命名為.h, 否則沒有c++頭文件語法提示
從數(shù)組中載入大數(shù)p,q,g
建立ossl_param, 設(shè)置參數(shù)的p,q,g
用參數(shù)初始化_evp_pkey_ctx, 得到_evp_pkey_dsa
打印_evp_pkey_dsa的共有數(shù)據(jù)(p,q,g …) + 參數(shù)
openssl3.2 - 官方demo學(xué)習(xí) - pkey - EVP_PKEY_DSA_paramfromdata.c
pkey - EVP_PKEY_DSA_paramgen.c
產(chǎn)生DSA的_evp_pkey_ctx
初始化_evp_pkey_ctx
設(shè)置參數(shù)到_evp_pkey_ctx
由_evp_pkey_ctx產(chǎn)生_evp_pkey
打印_evp_pkey公開值和DSA param
openssl3.2 - 官方demo學(xué)習(xí) - pkey - EVP_PKEY_DSA_paramgen.c
pkey - EVP_PKEY_DSA_paramvalidate.c
OPENSSL_hexstr2buf_ex 將16禁止字符串填充到16進制buffer
BIO_new_mem_buf 有用, 可以內(nèi)存的內(nèi)容轉(zhuǎn)為bio, 不用非要落地為文件才能操作
將buffer中寫的DSA param 載入到bio
從bio產(chǎn)生_evp_pkey_dsa
從 pkey產(chǎn)生 _evp_pkey_ctx1, 檢查 _evp_pkey_ctx1的param
設(shè)置新的param, 和 _evp_pkey_dsa 一起, 產(chǎn)生新的_evp_pkey_ctx2, 檢查 _evp_pkey_ctx2的param
再次設(shè)置一個新的param, 用OSSL_PARAM_merge合并_evp_pkey_ctx2的param, 作為新的param
用新的param產(chǎn)生新的ctx => _evp_pkey_ctx3, 檢查 _evp_pkey_ctx3的參數(shù)
取 _evp_pkey_ctx3的EVP_PKEY, 并打印EVP_PKEY的公用參數(shù)和param
openssl3.2 - 官方demo學(xué)習(xí) - pkey - EVP_PKEY_DSA_paramvalidate.c
pkey - EVP_PKEY_EC_keygen.c
給定橢圓曲線名字, 產(chǎn)生上下文_evp_pkey_ctx
設(shè)置_evp_pkey_ctx的橢圓曲線參數(shù)(有默認(rèn)參數(shù), 不用特意設(shè)置, 給熟悉的人用), 不熟悉密碼學(xué)的人, 只選橢圓曲線的名字就行
從_evp_pkey_ctx產(chǎn)生ec key;
打印 ec EVP_PKEY 的值(可以取出橢圓曲線的名字, 公鑰, 私鑰).
openssl3.2 - 官方demo學(xué)習(xí) - pkey - EVP_PKEY_EC_keygen.c
pkey - EVP_PKEY_RSA_keygen.c
官方指出 : RSA key 如果小于2048位, 就屬于弱key
官方demo中, 給出的默認(rèn)key長度為4096位
從名字生成上下文
初始化上下文
設(shè)置上下的key位數(shù)
設(shè)置質(zhì)數(shù)數(shù)量為2
產(chǎn)生RSA Key. (在我的本本上, 單步調(diào)試時, 感覺產(chǎn)生 RSA key時, 卡了一下, 大概不到1秒鐘)
打印rsa key內(nèi)容(可以得到 n, e, d, p, q, key的位數(shù), 公鑰, 私鑰)
PEM_write_x時, 如果文件句柄是具體的文件, 就是將公鑰/密鑰保存成了PEM文件.
openssl3.2 - 官方demo學(xué)習(xí) - pkey - EVP_PKEY_RSA_keygen.c
signature
signature - rsa_pss_direct.c
用RSA私鑰簽名
d2i_PrivateKey_ex()可以從內(nèi)存載入私鑰數(shù)據(jù), 得到私鑰EVP_PKEY*
從私鑰產(chǎn)生ctx, 對ctx進行簽名初始化, 設(shè)置ctx的padding填充模式
摘要算法選用SHA256, 對ctx設(shè)置摘要算法
嘗試簽名, 得到簽名長度, 然后進行私鑰簽名, 得到私鑰簽名buffer.
用RSA公鑰驗簽
d2i_PublicKey()可以從內(nèi)存載入公鑰數(shù)據(jù), 得到公鑰EVP_PKEY*
驗簽時使用的摘要算法要和簽名時一樣.
驗簽初始化, 對ctx進行驗簽初始化, 這是ctx的padding填充模式(要和簽名時一樣)
進行驗簽
openssl3.2 - 官方demo學(xué)習(xí) - signature - rsa_pss_direct.c
signature - rsa_pss_hash.c
對私鑰對明文做簽名(摘要算法為SHA256)
用公鑰對密文做驗簽(摘要算法為SHA256)
openssl3.2 - 官方demo學(xué)習(xí) - signature - rsa_pss_hash.c
signature - EVP_DSA_Signature_demo.c
DSA簽名(摘要算法SHA256), DSA驗簽(摘要算法SHA256)
簽名 : 用發(fā)送者的私鑰進行簽名.
驗簽 : 用發(fā)送者的公鑰進行驗簽.
看下API調(diào)用順序就行, 自己弄的時候, 跟著demo的流程弄就行.
對于openssl3.2, 越看越眼熟了.
openssl3.2 - 官方demo學(xué)習(xí) - signature - EVP_DSA_Signature_demo.c
signature - EVP_ED_Signature_demo.c
ED25519 簽名/驗簽算法, 現(xiàn)在是最好的.
產(chǎn)生ED25519私鑰/公鑰
用私鑰對明文簽名, 得到簽名數(shù)據(jù)
用公鑰對明文和簽名數(shù)據(jù)進行驗簽
openssl3.2 - 官方demo學(xué)習(xí) - signature - EVP_ED_Signature_demo.c
signature - EVP_EC_Signature_demo.c
EC的簽名/驗簽實現(xiàn), 摘要算法為 SHA3-512
簽名驗簽時的update銘文可以進行多次.
openssl的API封裝的真好, 只要是一類流程(e.g. 簽名/驗簽), 采用不同算法時, 差別不大.
以前看資料, 那個老師說, 最好不要用名字來取算法指針, 容易寫錯. 而且調(diào)用的API比較麻煩.
已經(jīng)單步調(diào)試了幾十個官方demo, 官方全部采用名稱字符串來取東西.
說明, 用名字取東西, 才可以讓同一類操作的維護性最好.
看了一眼openSSL的底層用名字取東西的實現(xiàn), 人家是做了一個Map, Map的成員是一個結(jié)構(gòu)指針, 里面有名字和任務(wù)指針.
沒仔細看, Map的Key應(yīng)該是個hash值, 效率肯定剛剛的.
至于名稱字符串容易寫錯, 自己準(zhǔn)備一個用名字取東西的API的名字有效值的文檔就可以搞定這個問題.
openssl3.2 - 官方demo學(xué)習(xí) - 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學(xué)習(xí) - smime - smenc.c
smime - smdec.c
從pem證書中得到x509*和私鑰, 用私鑰和證書解密MIME格式的PKCS7密文, 并保存解密后的明文
MIME的數(shù)據(jù)操作, 都是PKCS7相關(guān)的
openssl3.2 - 官方demo學(xué)習(xí) - smime - smdec.c
smime - smsign.c
從證書中得到X509*和私鑰指針
用證書和私鑰對銘文進行簽名, 得到簽名后的pkcs7指針
將pkcs7指向的bio_in, 寫為MIME格式的簽名密文
BIO_reset() 可以將一個bio恢復(fù)到剛打開的狀態(tài)(應(yīng)該就是將文件指針重新指向文件頭部), 一般用于只讀打開的場景
經(jīng)常用于多個對象要操作同一個bio的場景(一先一后的操作).
openssl3.2 - 官方demo學(xué)習(xí) - smime - smsign.c
smime - smsign2.c
PKCS7聯(lián)合簽名
從N張證書中, 分別得到N對(x509和私鑰)
對明文進行簽名(只是指定了bio_in和flag), 得到pkcs7*
對此pkcs7進行附加簽名者的操作(指定證書和私鑰), 有幾個聯(lián)合簽名者, 就進行幾次操作
將簽名數(shù)據(jù)pkcs7寫為密文
openssl3.2 - 官方demo學(xué)習(xí) - smime - smsign2.c
smime - smver.c
對于簽名文件(不管是單獨簽名, 還是聯(lián)合簽名), 都要用頂層證書進行驗簽(靠近根CA的證書)
讀證書文件, 得到x509*, 添加到證書容器
讀取簽名密文, 得到pkcs7*和密文的bio
進行pkcs7驗簽, 并將驗簽得到的簽名的明文寫到文件.
openssl3.2 - 官方demo學(xué)習(xí) - smime - smver.c
sslecho - main.c
簡單的echo TLS客戶端和服務(wù)器, 都在一個工程中, 用命令行參數(shù)來區(qū)分客戶端和服務(wù)器邏輯.
里面包含了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文章來源:http://www.zghlxwxcb.cn/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命令行整理文章來源地址http://www.zghlxwxcb.cn/news/detail-788321.html
END
到了這里,關(guān)于openssl3.2 - 官方demo學(xué)習(xí) - 索引貼的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!