1. 程式人生 > >TLS1.2協議設計原理

TLS1.2協議設計原理

[TOC] ## 前言 最近對[TLS1.2](https://tools.ietf.org/html/rfc5246)協議處理流程進行了學習及實現,本篇文章對TLS1.2的理論知識和處理流程進行分析,TLS協議的實現建議直接看[The Transport Layer Security (TLS) Protocol Version 1.2](https://tools.ietf.org/html/rfc5246) ## 為什麼需要TLS協議 通常我們使用TCP協議或UDP協議進行網路通訊。[TCP協議](https://tools.ietf.org/html/rfc793)提供一種面向連線的、可靠的位元組流服務。但是TCP並不提供資料的加密,也不提供資料的合法性校驗。 我們通常可以對資料進行加密、簽名、摘要等操作來保證資料的安全。目前常見的加密方式有對稱加密和非對稱加密。使用對稱加密,雙方使用共享金鑰。 ![](https://bkimg.cdn.bcebos.com/pic/377adab44aed2e736ab19f6a8401a18b87d6fa18?x-bce-process=image/watermark,g_7,image_d2F0ZXIvYmFpa2UyMjA=,xp_5,yp_5) 但是對於部署在網際網路上的服務,如果我們為每個客戶端都使用相同的對稱加密金鑰,那麼任何人都可以將資料解密,那麼資料的隱私性將得不到保障。 如果我們使用非對稱金鑰加密,客戶端使用服務端的公鑰進行公鑰加密,服務端在私鑰不洩露的情況下,只有服務端可以使用私鑰可以對資料進行解密,從而保障資料的隱私性,但是非對稱加密比對稱加密的成本高得多。 ![20200620164047.png](https://img2020.cnblogs.com/blog/580757/202006/580757-20200620164049216-1287132470.png) 我們可以採用對稱加密和非對稱加密相結合的方式實現資料的隱私性的同時效能又不至於太差。 1. 首先客戶端和服務端通過一個稱為金鑰交換的流程進行金鑰協商及交換金鑰所繫的資訊。 2. 通過公鑰加密對稱金鑰保證對稱金鑰的安全傳輸。 3. 服務端使用私鑰解密出對稱金鑰。 4. 最後雙方使用協商好的對稱金鑰對資料進行加解密。 TLS協議就是實現了這一過程安全協議。TLS是在TCP之上,應用層之下實現的網路安全方案。在TCP/IP四層網路模型中屬於應用層協議。TLS協議在兩個通訊應用程式之間提供資料保密性和資料完整性,另外還提供了連線身份可靠性方案。 > UDP則使用DTLS協議實現安全傳輸,和TLS協議類似。 ## 發展歷史 TLS協議的前身SSL協議是網景公司設計的主要用於Web的安全傳輸協議,這種協議在Web上獲得了廣泛的應用。 * 1994年,網景公司設計了SSL協議的1.0版,因為存在嚴重的安全漏洞,未公開。 * 2.0版本在1995年2月釋出,但因為存在數個嚴重的安全漏洞(比如使用MD5摘要、握手訊息沒有保護等),2011年[RFC 6176](https://tools.ietf.org/html/rfc6176) 標準棄用了SSL 2.0。 * 3.0版本在1996年釋出,是由網景工程師完全重新設計的,同時寫入RFC,較新版本的SSL/TLS基於SSL 3.0。2015年,[RFC 7568](https://tools.ietf.org/html/rfc7568) 標準棄用了SSL 3.0。 * 1999年,IETF將SSL標準化,並將其稱為TLS(Transport Layer Security)。從技術上講,[TLS 1.0](https://tools.ietf.org/html/rfc2246)與SSL 3.0的差異非常微小。 * TLS 1.1在RFC 4346中定義,於2006年4月發表,主要修復了CBC模式的BEAST攻擊等漏洞。 >微軟、Google、蘋果、Mozilla四家瀏覽器業者將在2020年終止支援TLS 1.0及1.1版。 * TLS 1.2在RFC 5246中定義,於2008年8月發表,添加了增加AEAD加密演算法,如支援GCM模式的AES。 * TLS 1.3在RFC 8446中定義,於2018年8月發表,砍掉了AEAD之外的加密方式。 ## 協議設計目標 1. 加密安全:TLS應用於雙方之間建立安全連線,通過加密,簽名,資料摘要保障資訊保安。 2. 互操作性:程式設計師在不清楚TLS協議的情況下,只要對端程式碼符合RFC標準的情況下都可以實現互操作。 3. 可擴充套件性:在必要時可以通過擴充套件機制新增新的公鑰和機密方法,避免建立新協議。 4. 相對效率:加密需要佔用大量CPU,尤其是公鑰操作。TLS協議握手完成後,通過對稱金鑰加密資料。TLS還集成了會話快取方案,減少需要從頭建立連線的情況。 ## 記錄協議 TLS協議是一個分層協議,第一層為TLS記錄層協議(Record Layer Protocol),該協議用於封裝各種高階協議。目前封裝了4種協議:握手協議(Handshake Protocol)、改變密碼標準協議(Change Cipher Spec Protocol)、應用程式資料協議(Application Data Protocol)和警報協議(Alert Protocol)。 >`Change Cipher Spec Protocol`在TLS1.3被去除。 ![20200522114622.png](https://img2020.cnblogs.com/blog/580757/202005/580757-20200522114623982-2045971987.png) 記錄層包含協議型別、版本號、長度、以及封裝的高層協議內容。記錄層頭部為固定5位元組大小。 ![20200522091116.png](https://img2020.cnblogs.com/blog/580757/202005/580757-20200522091117417-275634995.png) > 在TLS協議規定了,如接收到了未定義的協議協議型別,需要傳送一個`unexpected_message`警報。 ### 握手步驟 * 當客戶端連線到支援TLS協議的服務端要求建立安全連線並列出了受支援的演算法套件(包括加密演算法、雜湊演算法等),握手開始。 * 服務端從客戶端的演算法套件列表中指定自己支援的一個演算法套件,並通知客戶端,若沒有則使用一個預設的演算法套件。 * 服務端發回其數字證書,此證書通常包含服務端的名稱、受信任的證書頒發機構(CA)和服務端的公鑰。 * 客戶端確認其頒發的證書的有效性。 * 為了生成會話金鑰用於安全連線,客戶端使用服務端的公鑰加密隨機生成的金鑰,並將其傳送到服務端,只有服務端才能使用自己的私鑰解密。 * 利用隨機數,雙方生成用於加密和解密的對稱金鑰。這就是TLS協議的握手,握手完畢後的連線是安全的,直到連線(被)關閉。如果上述任何一個步驟失敗,TLS握手過程就會失敗,並且斷開所有的連線。 ### 握手協議 TLS 握手協議允許服務端和客戶端相互進行身份驗證,並在應用程式協議傳輸或接收其第一個位元組資料之前協商協議版本、會話ID、壓縮方法、金鑰套件、以及加密金鑰。 完整的TLS握手流程,流程如下 ``` Client Server ClientHello --------> ServerHello Certificate* ServerKeyExchange* CertificateRequest* <-------- ServerHelloDone Certificate* ClientKeyExchange CertificateVerify* [ChangeCipherSpec] Finished --------> [ChangeCipherSpec] <-------- Finished Application Data <-------> Application Data ``` > * 表示可選步驟或與實際握手情況相關。比如重建已有連線,服務端無需執行Certificate,再比如使用RSA公鑰加密時,無需ServerKeyExchange。 > 握手協議訊息必須按上面流程的傳送資料進行傳送,否則需要以致命錯誤告知對方並關閉連線。 完整的握手流程有時候也被稱為2-RTT流程,即完整的握手流程需要客戶端和服務端互動2次才能完成握手。 > 互動應用請求到響應的互動時間被稱為往返時間(Round-trip Time) 握手協議的結構如下,其中協議頭的ContentType固定為`22`,接下來是TLS版本號,TLS1.2為`0303`,最後是用2位元組表示長度。 ![20200525143145.png](https://img2020.cnblogs.com/blog/580757/202005/580757-20200525143143616-393187166.png) 握手協議型別包含以下: * hello_request:0 * client_hello:1 * server_hello:2 * certificate:3 * server_key_exchange :12 * certificate_request:13 * server_hello_done:14 * certificate_verify:15 * client_key_exchange:16 * finished:20 > Hello Message是具體的握手協議型別內容,不同協議內容有所不同。 #### Hello Request `Hello Request`訊息用於客戶端與服務端重新協商握手,該訊息可能由服務端在任何時刻傳送。`Hello Request`訊息非常簡單,沒有其他冗餘資訊。 ![20200525102316.png](https://img2020.cnblogs.com/blog/580757/202005/580757-20200525102314802-208204372.png) 當客戶端收到了服務端的`Hello Request`時可以有以下4種行為: * 當客戶端正在協商會話,可以忽略該訊息。 * 若客戶端未在協商會話但不希望重新協商時,可以忽略該訊息。 * 若客戶端未在協商會話但不希望重新協商時,可以傳送`no_renegotiation`警報。 * 若客戶端希望重新協商會話,則需要傳送`ClientHello`重新進行TLS握手。 服務端傳送完`HelloRequest`訊息,可以有以下幾種行為: * 服務端傳送了`HelloRequest`訊息,但未收到`ClientHello`時,可以通過致命連線警報關閉連線。 * 服務端傳送了`HelloRequest`訊息,必須等待握手協商處理完成後才可以繼續處理應用資料訊息。 > Finished和Certificate的握手訊息驗證不包括該訊息的hash。 #### Client Hello 當客戶端首次與服務端建立連線或需要重新協商加密握手會話時,需要將`Client Hello`作為第一條訊息傳送給服務端。 `Client Hello`訊息包含了許多重要資訊,包括客戶端版本號、客戶端隨機數、會話ID、金鑰套件、壓縮方式、擴充套件欄位等。 ![20200619180114.png](https://img2020.cnblogs.com/blog/580757/202006/580757-20200619180115040-824816941.png) * 客戶端版本號:客戶端支援的最新TLS版本號,服務端會根據該協議號進行協議協商。 * 32位隨機數:客戶端生成的32位隨機數。前4位是Unix時間戳,該時間戳為1970年1月1日0點以來的秒數。不過TLS並沒有強制要求校驗該時間戳,因此允許定義為其他值。後面28位為一個隨機數。 > 通過前4位元組填寫時間方式,有效的避免了週期性的出現一樣的隨機數。使得"隨機"更加"隨機"。 > 在TLS握手時,客戶端和服務端需要協商資料傳輸時的加密金鑰。為了保證加密金鑰的安全性。金鑰需要通過客戶端和服務端一起生成。客戶端和服務端都提供一個32位的隨機數,通過該隨機數使用基於HMAC的PRF演算法生成客戶端和服務端的金鑰。 * 會話ID:用於表示客戶端和服務端之間的會話。實際的會話ID是由服務端定義的,因此即使是新的連線,服務端返回的會話ID可能也會和客戶端不一致,由於會話ID是明文傳輸的,因此不能存放機密資訊。 * 若會話ID是新的,則客戶端和服務端需要建立完整的TLS握手連線流程。 * 若會話ID是較早連線的會話ID,則服務端可以選擇無需執行完整的握手協議。 * 演算法套件:客戶端將支援的加密演算法組合排列後傳送給服務端,從而和服務端協商加密演算法。服務端根據支援演算法在ServerHello返回一個最合適的演算法組合。 演算法套件的格式為TLS_金鑰交換演算法_身份認證演算法_WITH_對稱加密演算法_訊息摘要演算法,比如`TLS_DHE_RSA_WITH_AES_256_CBC_SHA256`,金鑰交換演算法是`DHE`,身份認證演算法是`RSA`,對稱加密演算法是AES_256_CBC,訊息摘要演算法是SHA256,由於RSA又可以用於加密也可以用於身份認證,因此金鑰交換演算法使用RSA時,只寫一個RSA,比如`TLS_RSA_WITH_AES_256_CBC_SHA256` * 壓縮方式:用於和服務端協商資料傳輸的壓縮方式。由於TLS壓縮存在安全漏洞,因此在TLS1.3中已經將TLS壓縮功能去除,TLS1.2演算法也建議不啟用壓縮功能。 * 擴充套件欄位:可以在不改變底層協議的情況下,新增附加功能。客戶端使用擴充套件請求其他功能,服務端若不提供這些功能,客戶端可能會中止握手。對於擴充套件欄位的詳細定義可以看[Transport Layer Security (TLS) Extensions](https://tools.ietf.org/html/rfc4366) > 客戶端傳送完 `ClientHello` 訊息後,將等待 `ServerHello` 訊息。 服務端返回的任何握手訊息(`HelloRequest` 除外)將被視為致命錯誤。 #### Server Hello 當服務端接收到`ClientHello`,則開始TLS握手流程, 服務端需要根據客戶端提供的加密套件,協商一個合適的演算法簇,其中包括對稱加密演算法、身份驗證演算法、非對稱加密演算法以及訊息摘要演算法。若服務端不能找到一個合適的演算法簇匹配項,則會響應握手失敗的預警訊息。 ![20200619180812.png](https://img2020.cnblogs.com/blog/580757/202006/580757-20200619180813635-153295467.png) * 版本號:服務端根據客戶端傳送的版本號返回一個服務端支援的最高版本號。若客戶端不支援服務端選擇的版本號,則客戶端必須傳送`protocol_version`警報訊息並關閉連線。 > 若服務端接收到的版本號小於當前支援的最高版本,且服務端希望與舊客戶端協商,則返回不大於客戶端版本的服務端最高版本。 > 若服務端僅支援大於client_version的版本,則必須傳送`protocol_version`警報訊息並關閉連線。 > 若服務端收到的版本號大於服務端支援的最高版本的版本,則必須返回服務端所支援的最高版本。 * 32位隨機數:服務端生成的32位隨機數,生成方式和客戶端一樣。服務端生成隨機數的可以有效的防範中間人攻擊,主要是通過防止重新握手後的[重放攻擊](https://security.stackexchange.com/questions/218491/why-using-the-premaster-secret-directly-would-be-vulnerable-to-replay-attack)。 * 會話ID:用於表示客戶端和服務端之間的會話。若客戶端提供了會話ID,則可以校驗是否與歷史會話匹配。 * 若不匹配,則服務端可以選擇直接使用客戶端的會話ID或根據自定義規則生成一個新的會話ID,客戶端需要儲存服務端返回的會話ID當作本次會話的ID。 * 若匹配,則可以直接執行1-RTT握手流程,返回ServerHello後直接返回`ChangeCipherSpec`和`Finished`訊息。 ``` Client Server ClientHello --------> ServerHello [ChangeCipherSpec] <-------- Finished [ChangeCipherSpec] Finished --------> Application Data <-------> Application Data ``` > 在Finished訊息中和完整握手一樣都需要校驗VerifyData。 * 演算法套件:服務端根據客戶端提供的演算法套件列表和自己當前支援演算法進行匹配,選擇一個最合適的演算法組合,若沒有匹配項,則使用預設的`TLS_RSA_WITH_AES_128_CBC_SHA`。 > TLS1.2協議要求客戶端和服務端都必須實現密碼套件`TLS_RSA_WITH_AES_128_CBC_SHA` * 壓縮方式:用於和服務端協商資料傳輸的壓縮方式。由於TLS壓縮存在安全漏洞,因此在TLS1.3中已經將TLS壓縮功能去除,TLS1.2演算法也建議不啟用壓縮功能。 * 擴充套件欄位:服務端需要支援接收具有擴充套件和沒有擴充套件的ClientHello。服務端響應的擴充套件型別必須是`ClientHello`出現過才行,否則客戶端必須響應`unsupported_extension`嚴重警告並中斷握手。 > [RFC 7568](https://tools.ietf.org/html/rfc7568)要求客戶端和服務端握手時不能傳送`{3,0}`版本,任何收到帶有協議Hello訊息的一方版本設定為`{3,0}`必須響應`protocol_version`警報訊息並關閉連線。 通過`ClientHello`和`ServerHello`,客戶端和服務端就協商好演算法套件和用於生成金鑰的隨機數。 #### Certificate 假設客戶端和服務端使用預設的`TLS_RSA_WITH_AES_128_CBC_SHA`演算法,在`ServerHello`完成後,服務端必須將本地的RSA證書傳給客戶端,以便客戶端和服務端之間可以進行非對稱加密保證對稱加密金鑰的安全性。 RSA的證書有2個作用: * 客戶端可以對服務端的證書進行合法性進行校驗。 * 對`Client Key Exchange`生成的pre-master key進行公鑰加密,保證只有服務端可以解密,確保對稱加密金鑰的安全性。 ![20200526135243.png](https://img2020.cnblogs.com/blog/580757/202005/580757-20200526135246621-696721414.png) 傳送給客戶端的是一系列證書,服務端的證書必須排列在第一位,排在後面的證書可以認證前面的證書。 當客戶端收到了服務端的`ServerHello`時,若客戶端也有證書需要服務端驗證,則通過該握手請求將客戶端的證書傳送給服務端,若客戶端沒有證書,則無需傳送證書請求到服務端。 > 證書必須為[X.509v3格式](https://baike.baidu.com/item/X.509/2817050?fr=aladdin)。 #### Server Key Exchange 使用RSA公鑰加密,必須要保證服務端私鑰的安全。若私鑰洩漏,則使用公鑰加密的對稱金鑰就不再安全。同時RSA是基於大數因式分解。金鑰位數必須足夠大才能避免金鑰被暴力破解。 > 1999年,RSA-155 (512 bits) 被成功分解。 > 2009年12月12日,RSA-768 (768 bits)也被成功分解。 > 在2013年的稜鏡門事件中,某個CA機構迫於美國政府壓力向其提交了CA的私鑰,這就是十分危險的。 相比之下,使用DH演算法通過雙方在不共享金鑰的情況下雙方就可以協商出共享金鑰,避免了金鑰的直接傳輸。DH演算法是基於離散對數,計算相對較慢。而基於橢圓曲線密碼(ECC)的DH演算法計算速度更快,而且用更小的Key就能達到RSA加密的安全級別。ECC金鑰長度為224~225位幾乎和RSA2048位具有相同的強度。 > ECDH:基於ECC的DH演算法。 另外在DH演算法下引入動態隨機數,可以避免金鑰直接傳輸。同時即使金鑰洩漏,也無法解密其他訊息,因為雙方生成的動態隨機數無法得知。 > 在密碼學中該特性被稱為[前向保密](https://zh.wikipedia.org/wiki/%E5%89%8D%E5%90%91%E4%BF%9D%E5%AF%86) > DHE: 通過引入動態隨機數,具有前向保密的DH演算法。 > ECDHE:通過引入動態隨機數,具有前保密的ECDH演算法。 #### Certificate Request 當需要TLS雙向認證的時候,若服務端需要驗證客戶端的證書,則向客戶端傳送`Certificate Request`請求獲取客戶端指定型別的證書。 * 服務端會指定客戶端的證書型別。 * 客戶端會確定是否有合適的證書。 #### Server Hello Done 當服務端處理Hello請求結束時,傳送`Server Hello Done`訊息,然後等待接收客戶端握手訊息。客戶端收到服務端該訊息,有必要時需要對服務端的證書進行有效性校驗。 ![20200526161422.png](https://img2020.cnblogs.com/blog/580757/202005/580757-20200526161424308-2087692628.png) #### Client Certificate 當客戶端收到了服務端的`CertificateRequest`請求時,需要傳送`Client Certificate`訊息,若客戶端無法提供證書,則仍要傳送此訊息,訊息內容可以不包含證書。 ![20200526135243.png](https://img2020.cnblogs.com/blog/580757/202005/580757-20200526135246621-696721414.png) #### Client Key Exchange 客戶端接收到ServerHelloDone訊息後,計算金鑰,通過傳送`Client Key Exchange`訊息給服務端。客戶端和服務端通過`Key Exchange`訊息交換金鑰,使得雙方的主金鑰協商達成一致。 ![20200526175211.png](https://img2020.cnblogs.com/blog/580757/202005/580757-20200526175212460-1534904649.png) 以RSA的金鑰協商為例。在`ClientHello`和`ServerHello`分別在客戶端和服務端建立了一個32位的隨機數。客戶端接收到`Server Hello Done`訊息時,生成最後一個48位的預主金鑰。通過服務端提供的證書進行公鑰加密,以保證只有服務端的私鑰才能解密。 > 其中預主金鑰的前2位要求使用`Client Hello`傳輸的TLS版本號(存在一些TLS客戶端傳遞的時協商後的TLS版本號,對該版本號檢查時可能會造成握手失敗)。 需要注意的是,若RSA證書的填空格式不正確,則可能會存在一個漏洞導致客戶端傳送的PreMasterSecret被中間人解密造成資料加密的對賬金鑰洩漏。可以看下[Attacking RSA-based Sessions in SSL/TLS](https://eprint.iacr.org/2003/052) #### Certificate Verify 若服務端要求客戶端傳送證書,且客戶端傳送了非0長度的證書,此時客戶端想要證明自己擁有該證書,則需要使用客戶端私鑰簽名一段資料傳送給服務端繼續驗證。該資料為客戶端收發的所有握手資料的hash值(不包括本次訊息)。 ![20200619203948.png](https://img2020.cnblogs.com/blog/580757/202006/580757-20200619203949761-1258998351.png) #### Finished 當傳送完`Change Cipher Spec`訊息後必須立即傳送該訊息。當該訊息用於驗證金鑰交換和身份驗證過程是否成功。 ![20200526175339.png](https://img2020.cnblogs.com/blog/580757/202005/580757-20200526175340642-1806058204.png) `Finished`訊息是第一個使用協商的演算法簇進行加密和防篡改保護的訊息。一旦雙方都通過了該訊息驗證,就完成了TLS握手。 VerifyData為客戶端收發的所有握手資料的hash值(不包括本次訊息)。與`Certificate Verify`的hash值可能會不一樣。如果傳送過`Certificate Verify`訊息,服務端的握手訊息會包含`Certificate Verify`握手的資料。 > 需要注意的是,握手資料不包括協議頭的握手協議明文資料(服務端返回`Finished`的驗證握手資料是包含接收到客戶端的`Finished`的明文hash值)。 > `Finished`訊息資料加密和`Appilication Data`一致,具體資料加密在`Application Data`段進行說明。 ### 改變密碼標準協議 改變密碼標準協議是為了在密碼策略中發出訊號轉換訊號。 該協議由一條訊息組成,該訊息在當前(不是掛起的)連線狀態下進行加密和壓縮。 訊息由值 1 的單個位元組組成。 ![20200525102627.png](https://img2020.cnblogs.com/blog/580757/202005/580757-20200525102625815-1928839073.png) > 在接收到該協議後,所有接收到的資料都需要解密。 ### 警報協議 警報訊息傳達訊息的嚴重性(警告或致命)和警報的說明。具有致命級別的警報訊息會導致立即終止連線。 若在改變密碼標準協議前接收到警報訊息,是明文傳輸的,無需解密。 ![20200525135543.png](https://img2020.cnblogs.com/blog/580757/202005/580757-20200525135542419-682331539.png) 與其他訊息一樣,警報訊息按當前連線狀態指定進行加密和壓縮。在接收到改變密碼標準協議後接收到警報協議,則需要進行解密。解密後即為警報協議明文格式。 ![20200525135556.png](https://img2020.cnblogs.com/blog/580757/202005/580757-20200525135555437-67640628.png) > 加密的Alert訊息和加密資料一樣,都需要遞增加密序號,在資料解密時,遞增解密序號。 ### 應用程式資料協議 當客戶端和服務端`Finished`傳送完畢並驗證通過後,握手就結束了。後續所有資料都會使用握手協商的對稱金鑰進行資料加密。 ![20200620173729.png](https://img2020.cnblogs.com/blog/580757/202006/580757-20200620173731523-689391474.png) TLS協議實現了資料加密和MAC計算。一般來說有3種加密模式,分別為: 1. Mac-then-Encrypt:在明文上計算MAC,將其附加到資料,然後加密明和+MAC的完整資料。 2. 加密和MAC:在明文上計算MAC,加密明文,然後將MAC附加到密文的末尾 3. Encrypt-then-Mac:加密明文,然後在密文上計算MAC,並將其附加到密文。 TLS協議使用的是`Mac-then-Encrypt`。首先將加密的序號、ContentType、資料長度、資料進計算HMAC-SHA256摘要。然後將摘要拼接到資料後,通過PKCS7格式對摘要+MAC資料進行填充對其和加密塊大小一致。最後`摘要+MAC+對其填充塊`進行加密。 需要注意的是應用程式資料訊息有最大長度限制`2^14 + 2048`,當超過長度後,資料需要分段傳輸。每一段都當作單獨的資料段進行單獨MAC地址並加密。 ## 結語 TLS1.2版本是目前最常用的TLS協議,TLS1.3版本於2018年發表,目前並沒有廣泛使用。 使用TLS1.2需要注意以下幾點: 1. 若使用RSA非對稱加密,則需要儘可能使用2048位長度的金鑰。 2. 儘可能可以使用具有前向安全性的加密演算法,如ECDHE演算法進行非對稱加密。 3. 使用AEAD認證加密(GCM)代替CBC塊加密。 ## 參考文獻 1. [The Transport Layer Security (TLS) Protocol Version 1.2](https://tools.ietf.org/html/rfc5246) 2. [TLS發展歷史](https://baike.baidu.com/item/TLS/2979545?fr=aladdin#3) 3. [前向安全性](https://baike.baidu.com/item/前向安全性/6357798?fr=aladdin) 4. [TLS/SSL 協議詳解 (30) SSL中的RSA、DHE、ECDHE、ECDH流程與區別](https://blog.csdn.net/mrpre/article/details/78025940) 5. [TLS Extensions](https://blog.csdn.net/weixin_43364172/article/details/83988580) 6. [Session會話恢復:兩種簡短的握手總結SessionID&SessionTicket](https://blog.csdn.net/justinzengTM/article/details/105491809) 8. [Why using the premaster secret directly would be vulnerable to replay attack?](https://security.stackexchange.com/questions/218491/why-using-the-premaster-secret-directly-would-be-vulnerable-to-replay-attack) 9. [Why does the SSL/TLS handshake have a client and server random?](https://security.stackexchange.com/questions/89383/why-does-the-ssl-tls-handshake-have-a-client-and-server-random) 10. [Transport Layer Security (TLS) Extensions](https://tools.ietf.org/html/rfc4366) 11. [什麼是AEAD加密](https://zhuanlan.zhihu.com/p/28566058) 12. [Padding Oracle Attacks](https://tlseminar.github.io/padding-oracle/) 13. [Lucky13攻擊](http://www.vuln.cn/6500) 14. [Padding Oracle Attack](https://www.jianshu.com/p/833582b2f560) 15. [ssl perfect forward secrecy](https://vincent.bernat.ch/en/blog/2011-ssl-perfect-forward-secrecy) 16. [Transport Layer Security (TLS) Session Resumption without Server-Side State](https://tools.ietf.org/html/rfc5077) 17. [Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS)](https://tools.ietf.org/html/rfc4492) 18. [DTLS協議中client/server的認證過程和金鑰協商過程](https://www.cnblogs.com/god-of-death/p/893343