轉自:http://chuansong.me/n/1268791452834
二. TLS協議的原理
1. 自頂向下,分層抽象
構建軟件的常用方式是分層,把問題域抽象爲多層,每一層的概念定義爲一組原語,上一層利用下一層的組件構造實現,並被上一層使用,層層疊疊即成軟件。
-
例如在編程語言領域中,彙編語言爲一層,在彙編上面是C/C++等靜態編譯語言,C/C++之上是python/php/lua等動態類型腳本語言層,之上常常還會構造領域特定的DSL
-
在網絡架構中,以太網是一層,其上是ip協議的網絡層,ip之上是tcp等傳輸層,tcp之上是http等應用層
密碼學通信協議也是分層構造得到。大致可以這麼分層:
-
最底層是基礎算法原語的實現,例如: aes , rsa, md5, sha256,ecdsa, ecdh 等(舉的例子都是目前的主流選擇,下同)
-
其上是選定參數後,符合密碼學裏標準分類的算法,包括塊加密算法,簽名算法,非對稱加密算法,MAC算法等,例如: aes-128-cbc-pkcs7,rsaes-oaep ,rsassa-pkcs1-v1_5, hmac-sha256,ecdsa-p256,curve25519 等
-
再其上,是把多種標準算法組合而成的半成品組件,例如:對稱傳輸組件例如 aes-128-cbc + hmac-sha256,aes-128-gcm,認證密鑰協商算法: rsassa-OAEP + ecdh-secp256r1,數字信封:rsaes-oaep + aes-cbc-128 + hmac-sha256 ,文件密碼加密存儲組件:pbkdf2+aes-128-cbc-hmac-sha256,密鑰擴展算法 PRF-sha256 等
-
再其上,是用各種組件拼裝而成的各種成品密碼學協議/軟件,例如:tls協議,ssh協議,srp協議,gnupg文件格式,iMessage協議,bitcoin協議等等
第1層,一般程序員都有所瞭解,例如rsa,簡直路人皆知; md5 被廣泛使用(當然,也有廣泛的誤用)
第2層,各種莫名其妙的參數,一般很讓程序員摸不着頭腦,需要深入學習才能理清。
第3層,很多程序員自己造的輪子,往往說白了就是想重複實現第3層的某個組件而已。
第4層,正確地理解,使用,部署這類成熟的開放協議,並不是那麼容易。很多的誤用來源於不理解,需要密碼學背景知識,才能搞懂是什麼,爲什麼,怎麼用。
最難的是理論聯繫實際。面對一個一團亂麻的實際業務問題,最難的是從中抽象分析出其本質密碼學問題,然後用密碼學概念體系給業務建模。在分析建模過程中,要求必須有嚴密的,體系化的思考方式。不體系化的思考方式會導致疏漏,或者誤用。
第2層中,密碼學算法,常見的有下面幾類:
-
塊加密算法 block cipher: AES, Serpent, 等
-
流加密算法 stream cipher: RC4,ChaCha20 等
-
Hash函數 hash funtion:MD5,sha1,sha256,sha512 , ripemd 160,poly1305 等
-
消息驗證碼函數 message authentication code: HMAC-sha256,AEAD 等
-
密鑰交換 key exchange: DH,ECDH,RSA,PFS方式的(DHE,ECDHE)等
-
公鑰加密 public-key encryption: RSA,rabin-williams 等
-
數字簽名算法 signature algorithm:RSA,DSA,ECDSA (secp256r1 , ed25519) 等
-
密碼衍生函數 key derivation function: TLS-12-PRF(SHA-256) , bcrypto,scrypto,pbkdf2 等
-
隨機數生成器 random number generators: /dev/urandom 等
每個類別裏面的都有幾個算法不斷競爭,優勝劣汰,近幾十年不斷有老的算法被攻破被淘汰,新的算法被提出被推廣。這一塊話題廣,水很深,內容多,陷阱也多,後續byron會翻譯整理一系列文章,分享一下每一類裏面個人收集的資料。
在此推薦一下 [ 開源電子書crypto101] 鏈接
https://www.crypto101.io/ ,講的很透徹,而且很易讀)
設計一個加密通信協議的過程,就是自頂向下,逐步細化,挑選各類組件,拼裝成完整協議的過程
2. TLS CipherSuite
從上述分層的角度看,TLS大致是由3個組件拼成的:
-
1.對稱加密傳輸組件,例如aes-128-gcm(這幾個例子都是當前2015年最主流的選擇);
-
2.認證密鑰協商組件,例如rsa-ecdhe;
-
3.密鑰擴展組件,例如TLS-PRF-sha256
這些組件可以再拆分爲5類算法,在TLS中,這5類算法組合在一起,稱爲一個CipherSuite:
-
authentication (認證算法)
-
encryption (加密算法 )
-
message authentication code (消息認證碼算法 簡稱MAC)
-
key exchange (密鑰交換算法)
-
key derivation function (密鑰衍生算法)
TLS協議設計之初就考慮到了這每一類算法的演變,所以沒有定死算法,而是設計了一個算法協商過程,來允許加入新的算法( 簡直是軟件可擴展性設計的典範!),協商出的一個算法組合即一個CipherSuite
TLS CipherSuite 在 iana 集中註冊,每一個CipherSuite分配有 一個2字節的數字用來標識 ,可以在 [iana的註冊頁面] 鏈接
https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4 查看
iana註冊頁面截圖:
在瀏覽器中,就可以查看當前使用了什麼 CipherSuite,在地址欄上,點擊一個小鎖的標誌,就可以看到了。
服務器端支持的CipherSuite列表,如果是用的openssl,可以用 openssl ciphers -V | column -t 命令查看,輸出如:
例如其中這一行(這個是目前的主流配置):
0xC0,0x2F - ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD
表示:
名字爲ECDHE-RSA-AES128-GCM-SHA256
的CipherSuite ,用於 TLSv1.2版本,使用 ECDHE 做密鑰交換,使用RSA做認證,使用AES-128-gcm做加密算法,MAC由於gcm作爲一種aead模式並不需要,所以顯示爲aead,使用SHA256做PRF算法。
可以參考 [man 1 ciphers] 鏈接 http://linux.die.net/man/1/ciphers
要注意的是,由於歷史兼容原因,tls標準,和openssl的tls實現中,有一些極度不安全的CipherSuite,一定要禁用,比如:
-
EXP , EXPORT
: 一定要禁用。EXPORT表示上世紀美國出口限制弱化過的算法,早已經被攻破,TLS的FREAK 攻擊就是利用了這類坑爹的算法。 -
eNULL, NULL
: 一定要禁用。NULL表示不加密!默認是禁用的。 -
aNULL
: 一定要禁用。表示不做認證(authentication) ,也就是說可以隨意做中間人攻擊。 -
ADH
: 一定要禁用。表示不做認證的 DH 密鑰協商。
上面是舉個例子,讀者不要自己去研究怎麼配置,這太容易搞錯。
請按照mozilla官方給出的這個[權威文檔] 鏈接
https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations ,複製粘貼就好了。
CipherSuite的更多解釋,配置方法等,可以參考byron之前寫的一篇文章 [SSL/TLS CipherSuite 介紹] https://blog.helong.info/blog/2015/01/23/ssl_tls_ciphersuite_intro/
3. 協議分層
TLS是用來做加密數據傳輸的,因此它的主體當然是一個對稱加密傳輸組件。爲了給這個組件生成雙方共享的密鑰,因此就需要先搞一個認證密鑰協商組件,故,TLS協議自然分爲:
-
做對稱加密傳輸的record協議 ,the record protocol
-
做認證密鑰協商的handshake協議,the handshake protocol
還有3個很簡單的輔助協議:
-
changecipher spec 協議,the changecipher spec protocol, 用來通知對端從handshake切換到record協議(有點冗餘,在TLS1.3裏面已經被刪掉了)
-
alert協議,the alert protocol, 用來通知各種返回碼,
-
application data協議, The application data protocol,就是把http,smtp等的數據流傳入record層做處理並傳輸。
這種 認證密鑰協商 + 對稱加密傳輸 的結構,是絕大多數加密通信協議的通用結構,在後文的更多協議案例中,我們可以看到該結構一再出現。
這5個協議中:
record協議在tcp流上提供分包,
圖片來自網絡:
其它的: handshake protocol, alert protocol, changeCipherSpec protocol, application data protocol都封裝在record protocol的包裏,然後在tcp上傳輸(此處以tcp舉例,也有可能是udp,或者隨便什麼ipc機制等)
下文分別介紹,內容主要是翻譯自 RFC5246,RFC5077,RFC4492