前言

:SSL/TLS的本質其實是密碼學,不過作為一名開發人員對其基本的互動流程還是要清除的,所以本篇文章不涉及密碼學原理,因為密碼學是一門很難並且涉及到很多數學知識的方向,我也不會。

一、準備工作

測試環境

:Windows10

抓包工具

:Wireshark

(五)HTTPS抓包瞭解TLS握手流程

為了進行抓包時的規則過濾,只顯示固定ip的tcp資料包,所以我們首先要拿到伺服器的IP地址。

我們用百度來進行測試,首先ping百度的域名,得到經過DNS後我們能夠連線到的百度的伺服器的IP,不過這裡可以看到一個有意思的現象,我們原本ping的是

http://www。

baidu。com

,但顯示的結果卻是一個名為

http://www。

a。shifen。com

的域名:

(五)HTTPS抓包瞭解TLS握手流程

使用nslookup來看下

http://www。

baidu。com

http://www。

a。shifen。com

這兩個域名的DNS記錄:

(五)HTTPS抓包瞭解TLS握手流程

(五)HTTPS抓包瞭解TLS握手流程

可以看到在預設情況下我這臺機器的域名解析是由內網中IP為10。246。101。34這個DNS伺服器進行解析的,從域名解析的結果來看,

http://www。

baidu。com

http://www。

a。shifen。com

的一個CNAME記錄,與此同時該DNS伺服器中還記錄了

http://www。

a。shifen。com

的兩個A記錄:分別是180。101。49。42和180。101。49。11,也就是說在我這臺機器上訪問百度,目的IP是這兩個IP中的隨機一個,最終是哪個要由百度的負載均衡演算法來決定,所以我們在Wireshark中可以應該這樣指定過濾規則:

(五)HTTPS抓包瞭解TLS握手流程

然後在瀏覽器中直接輸入百度的網址

https://www。

baidu。com

,可以看到我們已經抓到了https連線過程相關的資料包:

(五)HTTPS抓包瞭解TLS握手流程

二、Wireshark資料包如何解讀

1、背景顏色

從圖上我們能夠看到有些資料包有許多的背景顏色,這些背景顏色是為了利於我們更直觀的瞭解包的屬性,其詳細資訊在檢視 - 著色規則選項卡中:

(五)HTTPS抓包瞭解TLS握手流程

可以看到顏色其實就是對應著一條條的過濾規則

2、資料包內容

雙擊一個數據包,我們可以看到這個包的具體內容

(五)HTTPS抓包瞭解TLS握手流程

瞭解過網路原理的同學都知道,在網路的分層結構中,下層給上層提供支援,上層對下層來首是透明的。OSI七層模型中,最下面四層分別是物理層、鏈路層、網路層、傳輸層,按順序對應上圖中的四種選項。整個資料包的封裝規則如下圖所示:

(五)HTTPS抓包瞭解TLS握手流程

(五)HTTPS抓包瞭解TLS握手流程

2.1 鏈路層幀頭

Frame即物理層資料幀,也就是整個要傳送的報文。Ethernet選項對應著乙太網幀的頭部資料,其資料範圍為如下圖中藍色的部分所示,共計14個位元組:

(五)HTTPS抓包瞭解TLS握手流程

從頭到尾分別是6位元組的目的MAC地址,6位元組的目的MAC地址,以及2位元組的網路協議版本。

(五)HTTPS抓包瞭解TLS握手流程

2.2 IP報文頭

緊跟著乙太網幀頭部的就是IP資料包,IP資料包最低長度為20個位元組,如下圖所示:

(五)HTTPS抓包瞭解TLS握手流程

從上到下按順序分別是4bit的版本、4bit的IP首部長度(單位為4位元組,所以IP首部長度最多為15*4=60位元組)、1位元組的服務型別、2位元組的資料報總長度(不包括乙太網幀頭和幀尾,只是IP資料報的長度,單位為1位元組)、2位元組的分組ID、3bit的分組標誌、13bit的片偏移量。其中分組ID、分組標誌、片偏移共同給IP資料報分組重整提供支援。分組ID相同的IP資料包被歸為同一個報文,標誌欄位最後一位MF=1時表示當前資料包不是最後一個,MF=0表示當前IP報文是原報文中的最後一個分組,片偏移表示當前IP報文在原報文中的位置,單位為8位元組,這也說明每個IP報文的長度一定是8位元組的倍數。

片偏移量後面是IP報文的生存時間TTL,佔用1個位元組,IP資料包每經過一個路由器轉發後TTL都會減1,當路由器發現經過自己的IP資料報的TTL值為0,則不再繼續轉發,而是直接將IP資料報丟棄。Linux中的traceroute命令和Windows中的tracert命令,就是依靠傳送不同TTL值的ICMP包來實現的:

(五)HTTPS抓包瞭解TLS握手流程

思考我們就能知道,這個底層其實就是分別傳送了TTL為1、2、3的三個ICMP報文。

生存時間後面是1位元組的高層協議型別,HTTPS底層使用的肯定是TCP連線,所以IP層的高層協議為傳輸層協議TCP。常見的有ICMP:1 TCP:6 UDP:17。協議型別後面是2位元組的首部校驗和、4位元組的源IP地址、4位元組的目的IP地址,另外這20位元組也被稱作固定IP首部。

雖然IP報文頭有40位元組的擴充套件選項,但是在實際使用時基本沒人用到IP的擴充套件頭,但是可以解析IP報文的軟體必須對這一功能提供支援。

(五)HTTPS抓包瞭解TLS握手流程

2.3 TCP首部和資料

在IP首部之後就是TCP首部了,然後緊跟在TCP首部之後的內容就是我們要傳送的資料,如下圖所示:

(五)HTTPS抓包瞭解TLS握手流程

按順序一次是2位元組的源埠、2位元組的目的埠(由於埠最多16位表示,所以計算機有效埠最大為2^16 - 1個)、4位元組的本次傳送的TCP報文首位元組序列號、4位元組的期望收到的TCP報文的首位元組序列號,即確認號、4bit的TCP首部長度(單位為4位元組,所以TCP首部最大也是15 * 4 = 60位元組)。

再後面的28bit有6bit的保留位,然後是6bit的標誌位,一個標誌1bit。其中後五個是我們需要特別注意的:

ACK為1時表明當前報文是一個應答報文,即確認號有效,通常來說ACK都會為1

PSH為1時表明在當前報文到達接收方網絡卡之後,其是否應該立即推送給上層,如果為0則由網絡卡暫時快取

RST為1時表明這是一個復位報文,當接收到一個RST為1的報文時,需要斷開當前已經建立的TCP連線

SYN為1時表明這是一個同步報文,SYN=1、ACK=0時表示這是一個客戶端請求建立連線的報文,

即三次握手中的第一個報文,

SYN=1、ACK=1時表明這是服務端同意客戶端建立連線請求並且順便請求

和客戶端建立連線的報文,即三次握手中的第二個報文,通常來說只有這兩個報文的SYN=1

FIN為1時表明這是一個結束報文,當FIN=1時相當於告訴對方,沒有資料要繼續傳送了可以斷開連線了

標誌位後面是2位元組的視窗大小,也就是允許接收方下次傳送TCP報文的最大長度,也就是說接收方下次傳送的TCP報文序列為[確認號, 確認號 + WindowSize - 1]

最後是2位元組的校驗和以及2位元組的緊急指標,如果有擴充套件欄位,後面還能追加最多40位元組的TCP擴充套件首部,與IP首部的擴充套件不同的是,TCP擴充套件首部經常會被用到:

MSS最大報文段長度、視窗擴大選項、時間戳選項等

(五)HTTPS抓包瞭解TLS握手流程

在瞭解了乙太網幀首部、IP報文首部、TCP報文首部的基本格式以及知道了如何在Wireshark抓到的包中檢視這些首部的內容,接下來就來分析一下https連線過程中都經歷了哪些過程。

三、HTTPS連線分析

1、TCP三次握手

從抓包結果來看,在訪問

https://www。

baidu。com

時最開始進行的是TCP的三次握手

(五)HTTPS抓包瞭解TLS握手流程

三次握手的過程如下:

(五)HTTPS抓包瞭解TLS握手流程

透過netstat命令我們可以看到機器上確實能夠看到已經和百度的伺服器建立的TCP連線

(五)HTTPS抓包瞭解TLS握手流程

握手成功,處於

ESTABLISHED

狀態。

2、TLS協議分層

從抓包結果可以看到,在TCP連線建立後,客戶端發出的第一個資料包如下:

(五)HTTPS抓包瞭解TLS握手流程

透過分析Wireshark資料表可以看到在傳輸層的下面又多了一層Transport Layer Security,即TLS層

(五)HTTPS抓包瞭解TLS握手流程

Wireshark中分出來的TLS層

(五)HTTPS抓包瞭解TLS握手流程

TCP資料包的載荷

從包的詳細資訊中可以看到在傳輸層下面又多了一層TLS層,

所以所謂的HTTPS協議,我們可以認為其就是在原來的OSI七層模型的傳輸層和應用層之間,又多了一層TLS層,但是其本質上還是屬於應用層的

。用一句話總結就是一端的應用將資料經過TLS加密後作為傳輸層TCP資料包的載荷傳送出去,對端在收到TCP包後拿出載荷再經過TLS層解密最終交付給應用,這就是HTTPS,比如在客戶端通常提供TLS層功能應用的就是瀏覽器,在服務端提供TLS層功能的應用就是Web容器。

接下來為了能夠更清楚的看到TLS握手的過程,我們修改抓到包的過濾條件,只看TLS協議的資料包:

(五)HTTPS抓包瞭解TLS握手流程

(五)HTTPS抓包瞭解TLS握手流程

透過抓包的結果我們可以看到,TLS資料包的型別是Wireshark可以獲取的。這會引發我們的一個思考,在前面提到過,HTTPS就是將加密的TLS資料包作為TCP的載荷進行通訊,既然TLS是加密的為什麼Wireshark還能獲取到這些基本資訊呢?想要弄清這個疑問就不得不瞭解TLS的分層結構。

TLS實際上又可以分為兩層:

第一層是靠近TCP層的TLS記錄層,TLS記錄層只有一種協議,即TLS記錄協議。第二層是在TLS記錄層的上層,這一層有幾種處於並列關係協議如:密碼切換協議、警告協議、握手協議等,雖然這一層通常被稱為TLS握手層,但需要注意的是TLS握手層不僅僅只有握手協議

(五)HTTPS抓包瞭解TLS握手流程

透過抓到的TLS資料包,我們可以很直觀的看到這個分層結構:

(五)HTTPS抓包瞭解TLS握手流程

(五)HTTPS抓包瞭解TLS握手流程

(五)HTTPS抓包瞭解TLS握手流程

(五)HTTPS抓包瞭解TLS握手流程

(五)HTTPS抓包瞭解TLS握手流程

TLS記錄層協議靠近TCP層,主要記錄了來自上層的TLS子協議的

型別、長度、版本

三個基本資訊,而這三個基本資訊並不是加密的,所以能夠被Wireshark解析出來。這也說明了TLS記錄層協議的工作就是記錄上層協議的一些元資料,以便於讓通訊的雙方能夠知道收到的TLS資料包的基本資訊從而能夠做出相應的處理。

從抓包到的結果來看,本機上使用的TLS版本為1。2,出現的TLS握手層協議有密碼切換協議(Change Cipher Spec)、警告協議(Alert)、握手協議(Handshake)、應用資料協議(Application Data)四種。每個TCP資料表可能包含多個TLS資料包,每個TLS資料包之間用TLS記錄層規則進行界線劃分,且每個TLS記錄層資料包中只能包含一個TLS握手層協議的資料包。

3、TLS記錄層

從抓包的結果可以看出我本機的TLS是1。2版本,所以我們只要論TLS1。2的相關內容。

TLS記錄層只有TLS記錄協議這一個協議,在TLS1。2版本中,傳送端其主要有以下四個功能:

資料分塊

資料壓縮

加密和完整性保護(主要分三種模式:流加密模式、分組模式、AEAD 模式)

新增訊息頭

相應的接收端也具有資料塊合併、資料解壓縮、資料解密等功能。

(五)HTTPS抓包瞭解TLS握手流程

傳送方的資料流動如上圖所示。TLS首先對應用層的資料進行分組,每一個分組都是一個TCP報文。分組後需要對應用層資料進行壓縮,壓縮完成之後還要透過MAC演算法,在原應用資料後新增一個摘要。經過壓縮和MAC演算法標記之後,所得到的資料依然是明文,此時需要經過資料加密,加密完成之後TLS記錄協議會給密文新增三個基本的訊息頭:握手層協議型別、TLS版本、密文長度。

TLS記錄層協議所用到的MAC演算法以及加密演算法是傳送方和接收方協商後決定的,具體的協商過程後面會提到。

由於TLS握手層相關的內容已經屬於密碼學範疇,密碼學極為複雜,所以我們就不分析了(水平不夠。。。),只需要知道他有哪些基本過程即可滿足我們日常開發需求。

4、TLS握手流程分析

在瞭解了TLS的協議分層結構之後,回過頭來看我們所抓到的資料包,結合實際的資料包來了解一下TLS的握手流程以及握手過程中產生了哪些資料的互動,TLS的握手流程如下圖所示:

(五)HTTPS抓包瞭解TLS握手流程

4.1 客戶端 —— Client Hello

首先是客戶端傳送了一個Client Hello報文:

(五)HTTPS抓包瞭解TLS握手流程

從抓到的資料包來看,其握手層協議型別為Handshake,主要資料內容有以下幾種:

Random: 一個客戶端隨機數,參與了SSL握手的 master key的計算、KDF計算、server_key_exchange的簽名值的計算

Cipher Suites:加密套件 主要分為四個部分,以加密套件 { ECDHE-ECDSA-AES256-SHA384 TLSv1。2 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA38 }為例,表示該加密套件適用於TLS1。2版本,秘鑰交換演算法為ECDH、認證演算法為ECDSA、資料加密演算法為AES(256)、MAC演算法為SHA38

Compression Methods: TLS記錄層協議鎖使用的資料壓縮演算法

Extension: 擴充套件選項 因為TLS在HTTP之前,此時尚無HTTP請求頭的概念,如果需要指定域名,則需要透過擴充套件選項server_name來指定

我們只需要大概瞭解這些欄位的基本含義即可,涉及到密碼學的東西有餘力的情況下再去以點破面自行了解。

4.2 服務端 —— Server Hello

在客戶端在收到客戶端發來的Client Hello包之後,會返回一個Server Hello包給客戶端

(五)HTTPS抓包瞭解TLS握手流程

Server Hello包中包含服務端生成的Random隨機數、TLS協議版本、Sesssion ID 和 資料壓縮方法,最主要的是返回了服務端根據Client Hello中的引數最終選擇的加密套件Cipher Suite。

4.3 服務端 —— Certificate、Server Key Exchange、Server Hello Done

服務端在返回了Server Hello資料包之後,緊接著向客戶端返回自己的證書和一個 Server Key Exchange報文,用於秘鑰協商,最後再發送一個Server Hello Done告訴客戶端SSL第一次握手結束了。

(五)HTTPS抓包瞭解TLS握手流程

(五)HTTPS抓包瞭解TLS握手流程

服務端返回的證書應該說是一個證書鏈,如上圖所示,可以看到服務端其實返回了兩個證書。一般來說,服務端證書鏈通常配置成三級,【站點證書】——【中間證書】——【根證書】,根證書通常是內建在作業系統或者支援HTTPS的應用當中的,所以為了減少開銷一般不會將根證書也返回。

【擴充套件】

:TLS分為單向認證和雙向認證兩種,顧名思義單向認證就是隻需要客戶端去驗證服務端的身份,而雙向認證需要服務端也要驗證客戶端的請求,但是十分消耗資源,導致效能低下,所以一般都不會開啟雙向認證。如果開啟了雙向認證,服務端還需要在Server Hello Done之前傳送一個CertificateRequest資料包,然後客戶端在收到Server Hello Done資料包之後需要向服務端傳送一個Certificate資料包。

4.4 客戶端 —— Client Key Exchange、ChangeCipher Spec、Encrypted Handshake Message

客戶端在收到服務端傳送來的Sever Hello Done包之後,開始驗證證書的有效性,如果證書有效之後,才會繼續進行這一步。驗證證書有效性主要包括:證書鏈是否可信、證書是否吊銷、證書有效期、域名檢驗。

(五)HTTPS抓包瞭解TLS握手流程

(五)HTTPS抓包瞭解TLS握手流程

證書驗證通過後,客戶端向服務端傳送的主要有這幾個引數:

client_key_exchange: 客戶端計算產生隨機數字pre-master,並且用服務端公鑰加密,傳送給服務端,客戶端以後具有自己的隨機數A和服務端的隨機數B,結合pre-master計算出協商得到的對稱秘鑰

change cipher spec:客戶端通知伺服器後續的同學新都採用協商的秘鑰進行加密通訊

encrypted handshake message: 計算前面向服務端傳送的資料生成一個hash作為摘要,並且使用協商秘鑰加密後,傳送到服務端進行資料和握手驗證

4.5 服務端 —— Change Cipher Spec、Encrypted Handshake Message

(五)HTTPS抓包瞭解TLS握手流程

服務端在收到客戶端的加密的pre - master後,透過自己的私鑰解密,然後根據簽名協商得到的隨機數A和B生成協商秘鑰,然後使用協商秘鑰解密被加密的摘要,再將前面接收到的所有客戶端傳送過來的相關安全引數進行hash之後,比較兩邊的摘要是否相同,從而驗證握手是否合法。驗證透過之後向客戶端傳送以下幾個資料包:

Change Cipher Spec: 服務端通知客戶端後續的通訊都採用協商秘鑰進行加密

Encrypted Handshake Message:服務端也將自己已經發送給客戶端的資料經過hash後再加密傳送給客戶端,讓客戶端進行有效性驗證

4.6 安全連線建立,傳送加密資料 —— Application Data

當客戶端收到服務端傳遞過來的Encryted Handshake Message,使用協商秘鑰解密並且驗證有效後,則說明連線成功建立,之後的所有資料將使用協商秘鑰進行加密:

(五)HTTPS抓包瞭解TLS握手流程

如下圖所示,加密後的資料透過TLS握手層的應用資料協議進行封裝,傳送給對:

(五)HTTPS抓包瞭解TLS握手流程

至此TLS/SSL安全連線就已經建立。