1. OpenSSL
1.1 OpenSSL簡介
SSL,Security Socket Layer,是一個安全傳輸協議,在Internet網上進行數據保護和身份確認。OpenSSL是一個開放源代碼的實現了SSL及相關加密技術的軟件包,由加拿大的Eric Yang等發起編寫的。OpenSSL的官方網站為http://www.openssl.org/,源代碼可以從ftp://ftp.openssl.org/source/上下載,也可以從OpenSSL的鏡像網站下載。
OpenSSL主要包括三個組件:openssl-多用途命令行工具;libcrypto-加密算法庫;libssl-加密模塊應用,主要實現TLS/SSL。
OpenSSL采用C語言作為開發語言,這使得OpenSSL具有優秀的跨平臺性能,這對于廣大技術人員來說是一件非常美妙的事情,可以在不同的平臺使用同樣熟悉的東西。OpenSSL支持Linux、Windows、BSD、Mac、VMS等平臺,這使得OpenSSL具有廣泛的適用性。但習慣C語言總比使用C++重新寫一個跟OpenSSL相同功能的軟件包輕松不少。
Openss的功能主要分為基本功能和輔助功能:基本功能,OpenSSL整個軟件包大概可以分成三個主要的功能部分:密碼算法庫、SSL協議庫以及應用程序。OpenSSL的目錄結構自然也是圍繞這三個功能部分進行規劃的。作為一個基于密碼學的安全開發包,OpenSSL提供的功能相當強大和全面,囊括了主要的密碼算法、常用的密鑰和證書封裝管理功能以及SSL協議,并提供了豐富的應用程序供測試或其它目的使用。輔助功能,
BIO機制是OpenSSL提供的一種高層IO接口,該接口封裝了幾乎所有類型的IO接口,如內存訪問、文件訪問以及Socket等。這使得代碼的重用性大幅度提高,OpenSSL提供API的復雜性也降低了很多。OpenSSL對于隨機數的生成和管理也提供了一整套的解決方法和支持API函數。隨機數的好壞是決定一個密鑰是否安全的重要前提。OpenSSL還提供了其它的一些輔助功能,如從口令生成密鑰的API,證書簽發和管理中的配置文件機制等等。
1.2 OpenSSL的幾個主要版本
OpenSSL 0.9.8(2005年)
- 新增支持sha256算法
- 新增支持DTLS
- 新增支持Win64系統
- 新增支持RSA X.931等
- 其他新增優化項
OpenSSL 1.0.2(2015)
- 新增支持DTLS1.2和TLS1.2
- 新增支持RSA-PSS, RSA-OAEP, ECDH and X9.42 DH等算法
- 其他新增、優化項
- will be supported until 2019-12-31.
OpenSSL 1.1.0 (2016)
- 新增ClientHello回調函數
- 刪除MIPS o32 ABI on IRIX的支持
- 新增對HKDF的支持
- 新增支持blake2b 和 blake2s
- 其他hug修復和優化
- will be supported until 2019-09-11.
OpenSSL 1.1.1(2018)
- 2018年9月發布,新版本支持TLS1.3協議
- 新增SM2算法支持
- 其他bug修改和優化
- will be supported until 2023-09-11 .
目前最新的穩定版本是OpenSSL 1.1.1,OpenSSL 1.0.2之前的版本都已經停止維護了,建議也是停止使用。具體的版本間的差異詳見https://github.com/openssl/openssl/blob/master/CHANGES
1.3 加密算法介紹
在生成數據證書是用戶可選擇不同的加密方式對數據進行加密,常見的加密算法可以分成三類,對稱加密算法,非對稱加密算法和摘要算法。
1.3.1 對稱加密
在對稱加密算法中,加密使用的密鑰和解密使用的密鑰是相同的。也就是說,加密和解密都是使用的同一個密鑰。因此對稱加密算法要保證安全性的話,密鑰要做好保密,只能讓使用的人知道,不能對外公開。在對稱加密算法中,加密和解密都是使用同一個密鑰,不區分公鑰和私鑰,對稱加密主要有四種模式:電子密碼本模式(ECB)、加密塊鏈模式(CBC)、加密反饋模式(CFB)、輸出反饋模式(OFB)。
對稱加密算法的優點在于加解密的高速度和使用長密鑰時的難破解性。假設兩個用戶需要使用對稱加密方法加密然后交換數據,則用戶最少需要2個密鑰并交換使用,如果企業內用戶有n個,則整個企業共需要n×(n-1) 個密鑰,密鑰的生成和分發將成為企業信息部門的惡夢。對稱加密算法的安全性取決于加密密鑰的保存情況,但要求企業中每一個持有密鑰的人都保守秘密是不可能的,他們通常會有意無意的把密鑰泄漏出去——如果一個用戶使用的密鑰被入侵者所獲得,入侵者便可以讀取該用戶密鑰加密的所有文檔,如果整個企業共用一個加密密鑰,那整個企業文檔的保密性便無從談起。
常見的對稱加密算法:DES、3DES、DESX、Blowfish、IDEA、RC4、RC5、RC6和AES。
DES是一種分組數據加密技術(先將數據分成固定長度的小數據塊,之后進行加密),速度較快,適用于大量數據加密,而3DES是一種基于DES的加密算法,使用3個不同密匙對同一個分組數據塊進行3次加密,如此以使得密文強度更高。
相較于DES和3DES算法而言,AES算法有著更高的速度和資源使用效率,安全級別也較之更高了,被稱為下一代加密標準。
1.2.2 非對稱加密
在非對稱加密算法中,加密使用的密鑰和解密使用的密鑰是不相同的,也稱為公私鑰加密,也就是說加密使用的密鑰和解密使用的密鑰不同。
假設兩個用戶要加密交換數據,雙方交換公鑰,使用時一方用對方的公鑰加密,另一方即可用自己的私鑰解密。如果企業中有n個用戶,企業需要生成n對密鑰,并分發n個公鑰。由于公鑰是可以公開的,用戶只要保管好自己的私鑰即可,因此加密密鑰的分發將變得十分簡單。同時,由于每個用戶的私鑰是唯一的,其他用戶除了可以可以通過信息發送者的公鑰來驗證信息的來源是否真實,還可以確保發送者無法否認曾發送過該信息。非對稱加密的缺點是加解密速度要遠遠慢于對稱加密,在某些極端情況下,甚至能比非對稱加密慢上1000倍。
常見的非對稱加密算法:RSA、ECC(移動設備用)、Diffie-Hellman、El Gamal、DSA(數字簽名用)。
RSA和DSA的安全性及其它各方面性能都差不多,而ECC較之則有著很多的性能優越,包括處理速度,帶寬要求,存儲空間等等。
1.2.3 摘要算法
摘要算法特別的地方在于它是一種單向算法,用戶可以通過Hash算法對目標信息生成一段特定長度的唯一的Hash值,卻不能通過這個Hash值重新獲得目標信息。因此Hash算法常用在不可還原的密碼存儲、信息完整性校驗等。
常見的Hash算法:MD2、MD4、MD5、HAVAL、SHA、SHA-1、HMAC、HMAC-MD5、HMAC-SHA1。
這幾種算法只生成一串不可逆的密文,經常用其效驗數據傳輸過程中是否經過修改,因為相同的生成算法對于同一明文只會生成唯一的密文,若相同算法生成的密文不同,則證明傳輸數據進行過了修改。通常在數據傳說過程前,使用MD5和SHA1算法均需要發送和接收數據雙方在數據傳送之前就知道密匙生成算法,而HMAC與之不同的是需要生成一個密匙,發送方用此密匙對數據進行摘要處理(生成密文),接收方再利用此密匙對接收到的數據進行摘要處理,再判斷生成的密文是否相同。
加密算法的效能通常可以按照算法本身的復雜程度、密鑰長度(密鑰越長越安全)、加解密速度等來衡量。上述的算法中,除了DES密鑰長度不夠、MD2速度較慢已逐漸被淘汰外,其他算法仍在目前的加密系統產品中使用。
2. 證書簡介
2.1 證書交互過程
在HTTP/HTTPS簡介一文中已經詳細介紹了HTTPS加密的核心技術TLS的通信流程。在通信流程中為什么HTTPS能夠做到數據的安全傳輸,是因為加密技術以及證書的應用。單向認證,證書交互相關的流程如下:
其中簽名的流程如下:
第一步,CA證書的明文消息會使用公開的摘要加密算法對明文信息進行摘要提取得到摘要信息;
第二步,CA機構使用自己的私鑰對第一步得到的摘要信息進行加密,得到的信息就是簽名;
第三步,CA機構會將明文信息和簽名信息放到證書中,這類證書就是數字證書了。所以數字證書主要包含了三方面的內容:證書所有者信息、證書所有者公鑰和證書頒發機構的簽名;
第四步,消息的接收者接收到數據之后,首先使用同樣的方法對原文進行消息摘要,得到摘要A,然后使用CA機構的公鑰給數字簽名進行解密,得到消息摘要B,最后比較摘要A和摘要B,如果相同,數據原文沒有被篡改,證書合法,否則就表示原文被篡改,證書不合法。
通過簽名認證后,就可以確定需要連接的服務器是合法的服務器。后面進一步與服務器的證書中的公鑰與服務器建立TLS連接(見HTTP/HTTPS簡介一文),最后交互數據采用對稱加密(TLS過程商量的對稱秘鑰)。
2.2 證書創建命令及API介紹
2.2.1 通過命令的方式創建證書,網上一搜一大把,這里簡單羅列一下相關的命令:
(1)、創建秘鑰對
openssl genrsa -out cert.key 2048
(2)、創建證書請求文件,此文件可以發送到CA機構進行簽名認證
openssl req -new -key cert.key -out certreq.pem
(3)、創建自簽名證書文件
openssl x509 -req -days 365 -in certreq.pem -signkey cert.key -out cert.pem
2.2.2 OpenSSL證書創建API介紹
(1)、RSA_generate_key(),EVP_PKEY_assign_RSA(),主要由此兩個函數生成證書秘鑰文件;
(2)、X509_REQ_set_pubkey()設置證書請求文件中的公鑰信息,X509_NAME_add_entry()、X509_REQ_set_subject_name()加入國家組織省份等信息;
(3)、X509_set_version()設置版本信息,ASN1_INTEGER_set()設置序列號,X509_set_subject_name()/X509_set_issuer_name()設置頒發者發行者信息、X509_time_adj()設置證書有效期信息、X509_sign()證書簽名
2.2.3 注意事項
(1)、初始化時重要API調用OpenSSL_add_all_algorithms(),該接口是OpenSSL中調用算法相關API的前提。不調用該API的后果就是程序直接退出,無異常報告,無斷點停留。
(2)、Nginx對應配置HTTPS相關選項
可以添加ssl_protocols指定TLS版本號碼,或者不填寫默認使用支持TLS1.2版本