TLS擴充套件的那些事
0x00 背景
TLS擴充套件於2003年以一個獨立的規範(RFC3456)被提出,之後被加入到TLS1.1和TLS1.2的版本中。它主要用於宣告協議對某些新功能的支援,或者攜帶在握手進行中需要的額外資料。TLS擴充套件機制使得協議在不改變本身基本行為的基礎上增加了額外的功能,因此從出現以來,它就成為協議功能不斷髮展的主要載體。
實際使用中,擴充套件以擴充套件塊的形式出現在ClientHello和ServerHello訊息的最後,例如我們訪問百度網站時,ClientHello資料包如下圖所示,其中Extensions Length
之後的欄位都是擴充套件欄位。在這一講中,我們對這些比較常見的擴充套件進行詳細的介紹。
0x01 概述
如上圖所示,各個擴充套件以擴充套件塊的形式並列出現。而每個擴充套件都以兩個位元組的表明擴充套件型別的欄位開始,後面接著擴充套件的資料。
Extension extensions;
struct {
ExtensionType extension_type;
opaque extension_data;
} Extension;
全部的擴充套件型別可以在IANA的網站看到,擴充套件資料的格式以及對TLS協議的影響由各個擴充套件的規範來規定。這裡我們主要介紹實際中比較常見的一些擴充套件。下表列出了我們接下來要介紹的一些副檔名稱以及對其功能的簡單介紹。
型別 | 副檔名稱 | 功能描述 |
---|---|---|
0xff01 | renegotiation_info | 表明可以支援安全的重協商 |
0x00 | server_name | 表明連線中要訪問的virtual hostname |
0x23 | session_ticket | 表明支援沒有狀態的會話恢復 |
0x0d | signature_algorithms | 表明支援的簽名演算法和雜湊函式對 |
0x05 | status_request | 表明支援OCSP Stapling |
0x3374 | next_protocol_negotiation | 表明支援NPN |
0x12 | signed_certificate_timestamp | 表明證書已透過Certificate Transparency公開 |
0x10 | application_layer_protocol_negotiation | 表明支援的應用層協議 |
0x02 詳細介紹
1.安全重協商
在介紹renegotiation_info
這個擴充套件之前,我們對TLS重協商機制進行簡單的描述。正常的TLS連線以握手開始,在交換資料之後關閉連線。但若通訊過程中雙方有一方請求重協商,那麼會再發生一次握手以協商出新的通訊安全引數。重協商可能會在以下幾種情況中出現:
- 需要客戶端證書的情況。一些網站會使用客戶端證書進行雙因子認證。一種部署方式是與網站的所有連線都要求使用客戶端證書,但這顯然是一種極不友好的方式,對於沒有客戶端證書的訪問者來說,網站不能向他們傳送任何資訊。另一種方式就是隻在某些子站點中要求客戶端證書,這樣當一個使用者訪問到子站點時,伺服器可以發起重協商以此來驗證客戶端證書。
- 資訊隱藏。因為第二次握手的資訊是由第一次的加密通道傳輸的,所以重協商的資訊(比如客戶端證書這樣可以表明使用者身份的資訊)可以被很好的保護,不被被動監聽者獲取。
- 改變加密強度。也有一些情況是站點的安全配置要求不一,在訪問到一些安全性要求高的子站點後,需要升級通訊的加密強度,此時也可以透過重協商完成。
協議規定客戶端可以在任何時候發起重協商,只需傳送一個新的ClientHello訊息。如果伺服器想要重協商,則向客戶端傳送一個HelloRequest訊息,告訴客戶端停止傳送加密資料並且發起一次新的握手。
最初設計的重協商機制無法抵禦如下圖所示的中間人攻擊。攻擊者可以在客戶端連線的開始注入任意的明文,無法保證TLS傳輸資料的完整性。
renegotiation_info擴充套件的提出就是為了阻止這種中間人攻擊,保證重協商是發生在之前已完成握手的雙方之間。一次由客戶端發起的重協商如下圖所示,在第一次握手中ClientHello訊息中包含一個沒有資料的renegotiation_info擴充套件,表明客戶端支援重協商,伺服器在ServerHello中也包含一個沒有資料的renegotiation_info擴充套件表明支援,並且在握手協商完成後,雙方將Finished訊息中的verify_data存在本地。之後客戶端要發起重協商時,傳送一個包含客戶端verify_data擴充套件的ClientHello訊息到伺服器,伺服器回覆一個包含客戶端和伺服器verify_data重協商擴充套件的ServerHello訊息表明願意重協商上一次的握手,之後重新協商通訊安全引數。
對於不支援擴充套件的SSL3,客戶端可以在密碼套件列表中加入TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0xff)表明對重協商的支援。
2.Server Name Indication(SNI)
SNI提供了一種機制,可以讓客戶端指明它想要連線的伺服器的名稱。也就是說server_name
這個擴充套件提供了對虛擬伺服器的支援,可以讓伺服器在眾多虛擬主機中找到相應的證書。比如一臺伺服器中有兩個虛擬主機,分別是alipay.com和baidu.com,若客戶端不指明其要訪問的主機名,則伺服器無法判斷應該回復支付寶還是百度的證書,那麼一個IP地址就只能有一個證書。
3.Session Tickets
Session Tickets提供了一種新的會話恢復機制。在介紹session_ticket
這個擴充套件之前,我們還是先對會話恢復進行簡單地描述。之前介紹的SSL握手的全部過程需要客戶端和伺服器的兩輪互動,其中的密碼學操作通常需要密集的CPU處理,且基於客戶端和伺服器證書驗證的身份認證還要更多的操作,因此開銷相對較大。而這種開銷可以透過恢復之前的會話來避免。
原本的會話恢復是基於客戶端和伺服器在第一次握手完成後儲存相關的會話安全引數。在第一次握手中,伺服器若想在之後恢復這個會話,則在ServerHello訊息中包含一個Session ID。之後若客戶端想要恢復這個會話,則在ClientHello中包含這個Session ID,伺服器在ServerHello中回覆相同的Session ID表明同意恢復會話,雙方根據上次握手中的master secret計算本次的金鑰,之後互發Finished訊息完成握手。這種握手只需要一輪互動,大大縮短了握手開銷。
而透過Session Tickets引入的這種會話恢復機制,則不需要伺服器端儲存任何資料。伺服器只需將恢復會話所需的資訊加密以ticket的形式傳送給客戶端。在第一次握手中,session ticket包含在New Session Ticket訊息中發給客戶端。
在客戶端想要恢復前面的某一會話時,就在ClientHello中包含那次會話的Session Ticket,伺服器決定接收後傳送ServerHello並繼續傳送ChangeCipherSpec。
4.簽名演算法
signature_algorithms
這個擴充套件是在TLS1.2中定義的,用於表明客戶端支援的簽名和雜湊演算法。這個擴充套件可有可無,若沒有,則伺服器從客戶端提供的密碼套件列表裡推斷支援的簽名演算法(比如RSA密碼套件就表明支援RSA簽名演算法),而直接假設支援的雜湊演算法是SHA1.
5.OCSP Stapling
status_request
這個擴充套件用於表明客戶端支援OCSP stapling。OCSP是一個檢查證書吊銷資訊的協議,OCSP stapling機制可以使伺服器向客戶端傳送最新的證書吊銷資訊,而無需客戶端去訪問CA的證書吊銷列表。
如上圖所示,在客戶端和伺服器都表明支援OCSP stapling後,伺服器在傳送完Certificate訊息後緊跟著傳送Certificate Status訊息,提供關於證書吊銷的必要資訊。
6.Certicate Transparency
signed_certificate_timestamp
擴充套件是Certificate Transparency(CT)運用在TLS協議中的一種體現。CT是為改善PKI現狀而提出的一種提議,它將所有證書都記錄下來。CA將其簽發的所有證書都提交給一個公共的log伺服器,並收到Signed Certificate Timestamp (SCT)作為提交的證據。在這個擴充套件機制中,SCT就透過ServerHello的擴充套件發給伺服器。
7.Application Layer Protocol Negotiation(ALPN)
application_layer_protocol_negotiation
擴充套件可以讓通訊雙方協商執行在TLS連線之上的應用層協議,比如SPDY,HTTP2.0等。客戶端在ClientHello中包含擴充套件欄位,裡面的內容是其支援的協議列表,伺服器在ServerHello中回覆的擴充套件欄位包含其選擇的協議。
值得注意的是客戶端支援的協議列表和伺服器最終選擇的結果都沒有被加密,任何可以看到流量的中間人都可以得知這些資訊。
8.Next Protocol Negotiation(NPN)
next_protocol_negotiation
擴充套件是為了支援NPN機制而引入的。而NPN是谷歌為了推廣SPDY的應用,解決防火牆問題和代理問題的前提下提出的。
與ALPN基本類似,只不過NPN為了保護最終的選擇結果,這個資訊是加密傳送的,也就是說在ChangeCipherSpec後傳送,這就需要引入一個新的訊息NextProtocol。由於需要引入新的握手訊息,並且選擇結果不被中間的裝置看到可能會有問題,因此TLS working group拒絕了這一方案,而是採用了ALPN。
0x03 結語
本講介紹了TLS協議的幾個常見擴充套件,希望對大家在深入理解TLS協議以及深入分析SSL資料包方面有所幫助。
注:本文涉及的基本知識來源於《BulletProof SSL and TLS》,這是一本講SSL很好的教材,推薦給大家。另本文內容是作者在教材內容的基礎上結合自己的理解及具體資料包分析寫作完成的,特此宣告。
相關文章
- 聊聊spring的那些擴充套件機制2018-09-21Spring套件
- 那些離不開的 Chrome 擴充套件外掛2019-03-03Chrome套件
- 聊聊Spring中的那些擴充套件機制2018-09-25Spring套件
- kotlin 擴充套件(擴充套件函式和擴充套件屬性)2019-02-26Kotlin套件函式
- 由事務擴充套件開談一談2021-05-15套件
- WCF擴充套件:行為擴充套件Behavior Extension2010-10-27套件
- ?用Chrome擴充套件管理器, 管理你的擴充套件2019-03-18Chrome套件
- 【Kotlin】擴充套件屬性、擴充套件函式2024-04-08Kotlin套件函式
- Sanic 擴充套件2019-04-21套件
- ORACLE 擴充套件2021-02-26Oracle套件
- 擴充套件工具2020-11-21套件
- 擴充套件歐幾里得2020-09-28套件
- DOM擴充套件2017-03-02套件
- 擴充套件ACL2017-11-28套件
- Lua擴充套件2016-08-16套件
- 照片擴充套件2015-05-28套件
- 擴充套件篇2015-05-22套件
- disable or 擴充套件2011-08-01套件
- 擴充套件表2011-03-31套件
- Mybatis擴充套件2024-08-14MyBatis套件
- PHP擴充套件開發就是一個自己的PHP擴充套件2020-11-05PHP套件
- 表空間自動擴充套件 AUTOALLOCATE 的擴充套件規律2010-07-19套件
- 正則的擴充套件2019-01-19套件
- SRAM的容量擴充套件2020-12-01套件
- JMeter 擴充套件開發:擴充套件 TCP 取樣器2022-12-01JMeter套件TCP
- ASP.NET Core擴充套件庫之Http通用擴充套件2021-04-19ASP.NET套件HTTP
- php7安裝redis擴充套件和memcache擴充套件2017-11-27PHPRedis套件
- PHPWAMP安裝Redis擴充套件的方式與相關擴充套件的下載2017-11-16PHPRedis套件
- [擴充套件推薦]Aliyun-oss-laravel —— Laravel最好的OSS Storage擴充套件2021-03-23套件Laravel
- Solon詳解(六)- Solon的校驗擴充套件框架使用與擴充套件2020-09-09套件框架
- 分類擴充套件2019-05-11套件
- 擴充套件表示式2021-09-09套件
- 新增php擴充套件2021-09-09PHP套件
- swift擴充套件Extensions2018-09-05Swift套件
- iOS 通知擴充套件2018-10-08iOS套件
- 可擴充套件性2020-12-10套件
- 19-擴充套件2020-11-27套件
- Nmap 擴充套件(四)2022-03-17套件