1.1 簡述
Openssl 是一個免費開源的工具包,實現了 TLS/SSL 協議和絕大多數的主流密碼算法和標准,最初的版本由 Eric A. Young 和
Tim J. Hudson 創建,其官方網站為 www.openssl.org。Openssl 主要包含三個部分:
(1)libssl -- TLS 協議的實現(RFC 8446);
(2)libcrypto -- 加密算法庫,支持絕大多數密碼算法,是實現 TLS 協議和 PKI 體系的基礎;
(3)openssl -- 命令行工具。
Openssl 當前主要的發布版本是 1.1.1,新開發的 Openssl3.0 相較於前者不論是架構體系還是設計理念都有了較大的變化。盡
管 Openssl 團隊發布聲明會盡量將這次的版本升級的影響降至最低,但是不可避免的,用戶在從 1.1.1 遷移至 3.0 仍然需要改動部
份程序,並且需要重新編譯應用程序。所以目前來看 Openssl3.0 這個版本並不兼容舊的版本,而且隨着時間的推移會逐步將一大部
分接口直接廢棄,特別是那些貼近底層的 API。
Openssl 團隊進一步優化了新版本架構,將各個模塊的耦合性進一步降低,並且提供了一個叫 “Provider” 的模式用來管理其他的
底層模塊,實現動態的、可插拔的底層實現。而對於應用層而言,用戶無需考慮各種底層實現,只需要專注於功能和應用,以下是
Openssl3.0 的整體架構設計圖(所有的設計圖片均摘錄自 Openssl3.0 官方設計草案,見參考資料):
按照我的理解,“Provider” 是一個抽象的概念,更像是一個標准。每個不同的 “Provider” 按照相同的標准實現相應的底層算法
和功能,然后通過 “Core” 模塊直接 “裝配” 到 Openssl 上,通過這種方式給頂層的應用程序提供密碼服務。這樣的設計增加了整體
結構的靈活性,除了可以隔離應用層和底層,使底層的變化不至於大范圍的影響應用層,還可以自己定制個性化的 “Provider” 以滿
足特殊的需求。
Openssl 3.0 的內核設計也是非常的有特色,內核可以緩存和調度各個 Provider, 使其可以各自獨立地工作互不影響,並且它和
EVP API 模塊有着非常緊密的聯系,如圖所示:
用戶首先會通過內核加載 Provider,在加載 Provider 的時候內核會將該 Provider 的相關信息包括算法實現全部加載到緩存區域
,用戶在使用該 Provider 提供的算法時會首先 “Fetch” 算法(其實就是查詢),然后內核會將該算法的實現提供給 EVP,然后用戶
通過 EVP 模塊調用算法,EVP 在這個過程扮演了一個代理的角色。
這里只是簡單介紹一下 Openssl3.0 的設計理念,其他具體的設計方案和代碼示例,讀者均可在 openssl 官網上查到,參考網址
可見本節末尾,這里不再討論。
我在這里特別說明一下:由於 Openssl 的代碼量十分龐大,單一個加密算法庫就有數十萬行的代碼,而且由於密碼學博大精深,
相關的數學原理更是晦澀難懂,筆者能力有限,不可能精通所有相關的知識,所以本系列的文章並不會針對 Openssl 的源碼進行深
入的討論,我只會在用戶層面對 Openssl 的加密算法庫做一些常用的 API 解讀,重在應用!如果涉及到我相對了解的知識,我會盡
量無保留地分享,文章有錯誤的話在所難免,我也歡迎各位讀者對我文中的錯誤進行批評指正!共同學習,共同進步!
作者假定各位讀者已經熟練掌握 C 語言和有基本的密碼學知識。
1.2 編譯和安裝
Openssl 的編譯十分簡單,步驟如下:
(1)在官網下載 openssl3.0.1 版本,得到 openssl-3.0.1.tar.gz;
(2)輸入 tar -zxvf openssl-3.0.1.tar.gz 解壓 tar 包到當前目錄;
(3)進入解壓后的目錄執行 ./Configure 生成 Makefile 文件(openssl 默認安裝到 /usr/local 下,如需指定安裝路徑,則執行
./Configure --prefix=/xxx/xxx);
(4)執行 make 編譯;
(5)執行 make install 安裝;
1.3 常用的編譯選項和配置
默認編譯生成 release 版本的共享庫,如果要生成可調式的庫,則輸入 ./Configure --debug,具體的編譯選項請查詢 INSTALL.md
文件。
1.4 openssl3.0 加密算法庫目錄結構
雖然我們的目標並不是完全精通 Openssl 的源碼,但是了解其源代碼目錄的含義仍然是有必要的:
aes -- AES 對稱算法實現;
aria -- ARIA 對稱算法實現;
asn1 -- ASN.1 編解碼實現;
aysnc -- 異步線程池實現;
bf -- blowfish 對稱算法實現;
bio -- I/O 流的抽象;
bn -- 大數運算實現;
buffer -- 內存緩沖區;
camellia -- Camellia 塊密碼算法;
chacha -- ChaCha20 流密碼算法;
cmac -- 基於分組密碼的消息認證碼;
cmp -- 證書管理協議;
cms -- 加密消息語法;
comp -- 壓縮算法;
conf -- 配置文件管理;
crmf -- 暫時不確定這個是做什么的;
ct -- 證書透明化(Certificate Transparency);
des -- des 對稱算法;
dh -- 密鑰交換協議;
dsa -- DSA簽名算法;
dso -- 動態庫管理;
ec -- 橢圓曲線算法;
encode_decode -- 編碼和解碼;
engine -- 引擎框架;
err -- 錯誤處理;
ess -- 增強安全服務(Enhanced Security Services);
evp -- 高層算法接口;
ffc -- 有限域加密;
hmac -- 基於 hash 的消息鑒別碼;
http -- http 協議實現;
idea -- 國際數據加密算法;
kdf -- 密鑰派生函數;
lhash -- 哈希鏈表實現;
md2 -- md2 摘要算法;
md4 -- md4 摘要算法;
md5 -- md5 摘要算法;
mdc2 -- mdc2 摘要算法;
modes -- 對稱算法的模式;
objects -- 對象管理;
ocsp -- 在線證書狀態協議;
pem -- PEM 編解碼實現;
pkcs7 -- 加密簽名消息語法標准 PKCS7 實現;
pkcs12 -- 個人信息交換語法標准 PKCS12 實現;
poly1305 -- Poly1305 消息認證碼;
providers -- 安全服務提供者,這個是 openssl3.0+ 最具特色的設計;
rand -- 隨機數;
rc2 -- RC2 對稱算法;
rc4 -- RC4 對稱算法;
rc5 -- RC5 對稱算法;
ripemd -- RACE原始完整性校驗消息摘要;
rsa -- RSA 非對稱算法;
seed -- 基於隨機種子的對稱加密算法;
sha -- sha1、sha256、sha512等摘要算法實現;
siphash -- SipHash 摘要算法;
sm2 -- 國密 sm2 橢圓曲線算法;
sm3 -- 國密 sm3 摘要算法;
sm4 -- 國密 sm4 分組加密算法;
srp -- 暫時不清楚是做什么的;
stack -- 棧的實現;
store -- 臨時存儲通道;
ts -- 可信時間?
txt_db -- 基於文本的數據庫;
ui -- 用戶接口;
whirlpool -- Whirlpool 散列算法;
x509 -- x509 證書系列標准實現。
參考資料:
1.Openssl 官方文檔 -- https://www.openssl.org/docs/
2.Openssl 設計草案 -- https://www.openssl.org/docs/OpenSSL300Design.html
2.Openssl Wiki -- https://wiki.openssl.org/index.php/Main_Page