SSL和TLS-TLS 1.3
SSL和TLS-TLS 1.3
TLS 1.3(版本號3,4)變化很大,比如新的訊息流和更強大的加密。
一個典型的SSL/TLS握手需要最少兩個RTTs,如果要驗證證書,需要更多次(下載和檢查CRLs,或者呼叫OSCP)。2010年,Google介紹和釋出了False Start技術,它的思想是客戶端傳送它的Finished訊息之後,立刻開始傳送應用資料(不等伺服器傳送Finished訊息),這樣節省了一個RTT。但是,該技術碰到了困難,沒進入TLS標準。
開始設計TLS 1.3的時候,他們記得TLS False Start,想採用類似的技術減少握手需要的RTTs數。於是,設計了新的訊息流。
TLS 1.3只要三次flights就可以建立一個TLS連線。跟TCP連線的建立類似,也需要交換三次訊息。
如果和OCSP stapling相結合,可以很快地建立一個安全的連線。第一個flight,客戶端傳送ClientHello訊息以後,立刻傳送ClientKeyShare訊息。ClientKeyShare訊息(type 18)代替了ClientKeyExchange。TLS 1.3不再支援靜態key交換,所以每個key交換必須是暫時的。ClientKeyShare訊息包含一組引數,客戶端支援的0個或者多個key交換方法。如果引數不被接受,或者伺服器不支援,伺服器就返回HelloRetryRequest訊息,客戶端就用另一個ClientKeyShare訊息重新開始握手。
一旦客戶端提供了合適的ClientKeyShare訊息,伺服器就響應一個ServerHello訊息。該訊息包含了伺服器選擇的協議版本、session ID、加密套件、隨機數和伺服器對客戶端的擴充套件資訊的響應。
TLS 1.3和以前的協議不同,伺服器的擴充套件被分成兩部分:ServerHello(裡邊的擴充套件沒加密)和EncryptedExtensions(裡邊的擴充套件加密了)。
伺服器然後生成它的key材料,傳送它的ServerKeyShare訊息(type 17)。伺服器然後計算共享的secret,傳送ChangeCipherSpec訊息,
拷貝pending write狀態到current write狀態。伺服器的其他訊息,都是用這個key加密的。除了Finished,下來的訊息都是可選的:
- 伺服器可以傳送EncryptedExtensions訊息,包含客戶端擴充套件(不是建立key所必須的)的響應。
- 如果需要被認證,在Certificate訊息裡傳送證書。
- 如果伺服器傳送了CertificateRequest訊息,客戶端要返回證書
- 如果伺服器沒被認證,然後它傳送CertificateVerify訊息,包含所有握手訊息的簽名。除了顯式伺服器認證之外,這還提供了握手完整性。
為了完成flight,伺服器傳送Finished訊息。
一旦客戶端接收到ServerKeyShare訊息,就可以計算premaster secret,派生出master secret和需要的全部key。客戶端傳送它的ChangeCipherSpec訊息,拷貝pending write狀態到current write狀態。
如果伺服器傳送了CertificateRequest訊息,客戶端必須響應一個Certificate訊息。該訊息可能是空的,沒有證書。
如果客戶端傳送了證書,一個數字簽名的CertificateVerify訊息也必須傳送給伺服器(證明私鑰是這個證書的)。
最後,客戶端傳送一個Finished訊息。一旦握手完成,客戶端和伺服器可以開始使用新建立的TLS連線交換應用資料。
Cipher Suites
TLS 1.3不再支援壓縮,靜態(RSA和DH)key交換,和non-AEAD加密。
- 對於壓縮,TLS 1.3的ClientHello訊息裡的支援方法列表只能是null。如果客戶端送了另一個值,伺服器必須生成fatal alert:illegal_parameter。
- 對於key交換,TLS 1.3不再支援任何靜態方法,例如RSA和DH,總是需要一個暫時的key交換。TLS 1.3只支援DHE和ECDHE。
- 對於加密,TLS 1.3不再支援non-AEAD加密。AEAD加密保護資料的機密性和真實性。AEAD需要key和IVs,可以忽略MAC keys。使用AEAD加密,加密的資料是TLSCompressed(或者TLSPlaintext)結構的fragment,認證的資料包含TLSPlaintext結構的順序號、type和version屬性。
Certificate Management
TLS 1.3繼續支援RSA、DSA和ECDSA簽名。
Alert Messages
TLS 1.3不支援壓縮,不再需要decompression_failure了。