目錄
- 簡介
- SSL/TLS協定
- NPN和ALPN
- 互動的例子
- 總結
自從HTTP從1.1更新到了2,一切都變得不同了。雖然HTTP2沒有強制說必須使用加密協定進行傳輸,但是業界的标準包括各大流行的浏覽器都隻支援HTTPS情況下的HTTP2協定。
那麼怎麼在HTTPS之中加入HTTP2協定的支援呢?今天本文将會跟大家聊一下SSL/TLS協定的擴充NPN和ALPN。
SSL(Secure Socket Layer)安全套接層,是1994年由Netscape公司設計的一套協定,并與1995年釋出了3.0版本。
TLS(Transport Layer Security)傳輸層安全是IETF在SSL3.0基礎上設計的協定,實際上相當于SSL的後續版本。
SSL/TLS是一種密碼通信架構,他是世界上使用最廣泛的密碼通信方法。

TLS主要分為兩層,底層的是TLS記錄協定,主要負責使用對稱密碼對消息進行加密。
上層的是TLS握手協定,主要分為握手協定,密碼規格變更協定和應用資料協定4個部分。
其中最重要的就是握手協定,通過用戶端和伺服器端的互動,和共享一些必要資訊,進而生成共享密鑰和互動證書。
接下來我們一步步的介紹每一步的含義:
-
client hello
用戶端向伺服器端發送一個client hello的消息,包含下面内容:
- 可用版本号
- 目前時間
- 用戶端随機數
- 會話ID
- 可用的密碼套件清單
- 可用的壓縮方式清單
我們之前提到了TLS其實是一套加密架構,其中的有些元件其實是可以替換的,這裡可用版本号,可用的密碼套件清單,可用的壓縮方式清單就是向伺服器詢問對方支援哪些服務。
用戶端随機數是一個由用戶端生成的随機數,用來生成對稱密鑰。
-
server hello
伺服器端收到client hello消息後,會向用戶端傳回一個server hello消息,包含如下内容:
- 使用的版本号
- 伺服器随機數
- 使用的密碼套件
- 使用的壓縮方式
使用的版本号,使用的密碼套件,使用的壓縮方式是對步驟1的回答。
伺服器随機數是一個由伺服器端生成的随機數,用來生成對稱密鑰。
-
可選步驟:certificate
伺服器端發送自己的證書清單,因為證書可能是層級結構的,是以處理伺服器自己的證書之外,還需要發送為伺服器簽名的證書。
用戶端将會對伺服器端的證書進行驗證。如果是以匿名的方式通信則不需要證書。
-
可選步驟:ServerKeyExchange
如果第三步的證書資訊不足,則可以發送ServerKeyExchange用來建構加密通道。
ServerKeyExchange的内容可能包含兩種形式:
- 如果選擇的是RSA協定,那麼傳遞的就是RSA建構公鑰密碼的參數(E,N)。我們回想一下RSA中建構公鑰的公式:\(密文=明文^E\ mod\ N\), 隻要知道了E和N,那麼就知道了RSA的公鑰,這裡傳遞的就是E,N兩個數字。具體内容可以參考RSA算法詳解
- 如果選擇的是Diff-Hellman密鑰交換協定,那麼傳遞的就是密鑰交換的參數,具體内容可以參考更加安全的密鑰生成方法Diffie-Hellman
-
可選步驟:CertificateRequest
如果是在一個受限通路的環境,比如fabric中,伺服器端也需要向用戶端索要證書。
如果并不需要用戶端認證,則不需要此步驟。
-
server hello done
伺服器端發送server hello done的消息告訴用戶端自己的消息結束了。
-
可選步驟:Certificate
對步驟5的回應,用戶端發送用戶端證書給伺服器
-
ClientKeyExchange
還是分兩種情況:
- 如果是公鑰或者RSA模式情況下,用戶端将根據用戶端生成的随機數和伺服器端生成的随機數,生成預備主密碼,通過該公鑰進行加密,返送給伺服器端。
- 如果使用的是Diff-Hellman密鑰交換協定,則用戶端會發送自己這一方要生成Diff-Hellman密鑰而需要公開的值。具體内容可以參考更加安全的密鑰生成方法Diffie-Hellman,這樣伺服器端可以根據這個公開值計算出預備主密碼。
-
可選步驟:CertificateVerify
用戶端向伺服器端證明自己是用戶端證書的持有者。
-
ChangeCipherSpec(準備切換密碼)
ChangeCipherSpec是密碼規格變更協定的消息,表示後面的消息将會以前面協商過的密鑰進行加密。
-
finished(握手協定結束)
用戶端告訴伺服器端握手協定結束了。
- 伺服器端告訴用戶端自己要切換密碼了。
- 伺服器端告訴用戶端,握手協定結束了。
-
切換到應用資料協定
這之後伺服器和用戶端就是以加密的方式進行溝通了。
上面我們介紹SSL/TLS協定的時候,最後一步是切換到應用資料協定,那麼用戶端是怎麼和伺服器端讨論協商具體使用哪種應用資料協定呢?是使用HTTP1.1?還是HTTP2?還是SPDY呢?
這裡就要用到TLS擴充協定了。而NPN(Next Protocol Negotiation) 和 ALPN (Application Layer Protocol Negotiation) 就是兩個TLS的擴充協定。
他們主要用在TLS中,用來協商用戶端和伺服器端到底應該使用什麼應用資料協定進行溝通。
其中NPN是SPDY使用的擴充,而ALPN是HTTP2使用的擴充。
他們兩個有什麼差別呢?
相較于NPN來說,ALPN在client hello消息中已經列出了用戶端支援的應用層協定,伺服器端隻需要從中選擇出它支援的協定即可。比NPN少了一個互動的步驟,是以ALPN是推薦的協定。
下面是具體的互動流程圖:
下面以ALPN為例,講解下具體的互動流程,首先是用戶端發送”Client Hello“消息:
Handshake Type: Client Hello (1) Length: 141 Version: TLS 1.2 (0x0303) Random: dd67b5943e5efd0740519f38071008b59efbd68ab3114587... Session ID Length: 0 Cipher Suites Length: 10 Cipher Suites (5 suites) Compression Methods Length: 1 Compression Methods (1 method) Extensions Length: 90 [other extensions omitted] Extension: application_layer_protocol_negotiation (len=14) Type: application_layer_protocol_negotiation (16) Length: 14 ALPN Extension Length: 12 ALPN Protocol ALPN string length: 2 ALPN Next Protocol: h2 ALPN string length: 8 ALPN Next Protocol: http/1.1
可以看到在client hello消息中的Extension字段中,使用了ALPN,并且列出了可以選擇使用的兩種ALPN Protocol:h2和http/1.1。
對應的“server hello” 消息會選擇出具體使用的ALPN protocol如下:
Handshake Type: Server Hello (2) Length: 94 Version: TLS 1.2 (0x0303) Random: 44e447964d7e8a7d3b404c4748423f02345241dcc9c7e332... Session ID Length: 32 Session ID: 7667476d1d698d0a90caa1d9a449be814b89a0b52f470e2d... Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) Compression Method: null (0) Extensions Length: 22 [other extensions omitted] Extension: application_layer_protocol_negotiation (len=5) Type: application_layer_protocol_negotiation (16) Length: 5 ALPN Extension Length: 3 ALPN Protocol ALPN string length: 2 ALPN Next Protocol: h2
如上所示,伺服器端選擇了h2, 最終當用戶端和伺服器端TLS握手結束之後,會選擇使用HTTP2作為後續的應用層資料協定。
NPN和ALPN都是TLS的擴充,相較而言,ALPN更加好用。
本文已收錄于 http://www.flydean.com/08-ssl-tls-npn-alpn/
最通俗的解讀,最深刻的幹貨,最簡潔的教程,衆多你不知道的小技巧等你來發現!
歡迎關注我的公衆号:「程式那些事」,懂技術,更懂你!