HTTPS抓包詳細分析

專題二:實際抓包分析

本文對百度搜索進行了兩次抓包,第一次抓包之前清理了瀏覽器的所有緩存;第二次抓包是在第一次抓包後的半分鐘內。

百度在2015年已經完成了百度搜索的全站https,這在國內https發展中具有重大的意義(目前BAT三大家中,只有百度宣稱自己完成了全站HTTPS)。所以這篇文章就以www.baidu.com爲例進行分析。

同時,作者採用的是chrome瀏覽器,chrome支持SNI (server Name Indication) 特性,對於HTTPS性能優化有很大的用處。

注:SNI是爲了解決一個服務器使用多個域名和證書的SSL/TLS擴展。一句話簡述它的工作原理就是:在和服務器建立SSL連接之前,先發送要訪問的域名(hostname),這樣服務器根據這個域名返回一個合適的證書。目前,大多數操作系統和瀏覽器都已經很好地支持SNI擴展,OpenSSL 0.9.8已經內置這一功能,新版的nginx和apache也支持SNI擴展特性。

本文抓包訪問的URL爲:http://www.baidu.com/  

(如果是https://www.baidu.com/,則以下結果不一樣!)

抓包結果:


可以看到,百度採用以下策略:

(1)對於高版本瀏覽器,如果支持 https,且加解密算法在TLS1.0 以上的,都將所有 http請求重定向到 https請求

(2)對於https請求,則不變。

【詳細解析過程】

1、TCP三次握手


可以看到,我的電腦訪問的是http://www.baidu.com/,在初次建立三次握手的時候, 客戶端是去連接 8080端口的(我所在小區網絡總出口做了一層總代理,因此,客戶端實際和代理機做的三次握手,代理機再幫客戶端去連接百度服務器)

2、tunnel建立

由於小區網關設置了代理訪問,因此,在進行https訪問的時候,客戶端需要和代理機做"HTTPS CONNECT tunnel" 連接(關於"HTTPS CONNECT tunnel"連接,可以理解爲:雖然後續的https請求都是代理機和百度服務器進行公私鑰連接和對稱密鑰交換,以及數據通信;但是,有了隧道連接之後,可以認爲客戶端也在直接和百度服務器進行通信。)

fiddler抓包結果:


3、client hello


3.1 隨機數

在客戶端問候中,有四個字節以Unix時間格式記錄了客戶端的協調世界時間(UTC)。協調世界時間是從1970年1月1日開始到當前時刻所經歷的秒數。在這個例子中,0x2516b84b就是協調世界時間。在他後面有28字節的隨機數random_C,在後面的過程中我們會用到這個隨機數。

3.2 SID(Session ID)

如果出於某種原因,對話中斷,就需要重新握手。爲了避免重新握手而造成的訪問效率低下,這時候引入了session ID的概念, session ID的思想很簡單,就是每一次對話都有一個編號(session ID)。如果對話中斷,下次重連的時候,只要客戶端給出這個編號,且服務器有這個編號的記錄,雙方就可以重新使用已有的“對稱密鑰”,而不必重新生成一把。

因爲我們抓包的時候,是幾個小時內第一次訪問https://www.baodu.com ,因此,這裏並沒有Session ID.稍會兒我們會看到隔了半分鐘,第二次抓包就有這個Session ID)  

session ID是目前所有瀏覽器都支持的方法,但是它的缺點在於session ID往往只保留在一臺服務器上。所以,如果客戶端的請求發到另一臺服務器(這是很有可能的,對於同一個域名,當流量很大的時候,往往後臺有幾十臺RS機在提供服務),就無法恢復對話。session ticket就是爲了解決這個問題而誕生的,目前只有Firefox和Chrome瀏覽器支持。

3.3 密文族(Cipher Suites)

RFC2246中建議了很多中組合,一般寫法是"密鑰交換算法-對稱加密算法-哈希算法,以“TLS_RSA_WITH_AES_256_CBC_SHA”爲例:

(a)TLS爲協議,RSA爲密鑰交換的算法;

(b)AES_256_CBC是對稱加密算法(其中256是密鑰長度,CBC是分組方式);

(c)SHA是哈希的算法。

瀏覽器支持的加密算法一般會比較多,而服務端會根據自身的業務情況選擇比較適合的加密組合發給客戶端。(比如綜合安全性以及速度、性能等因素)

3.4 Server_name擴展(一般瀏覽器也支持 SNI擴展)



當我們去訪問一個站點時,一定是先通過DNS解析出站點對應的ip地址,通過ip地址來訪問站點,由於很多時候一個ip地址是給很多的站點公用,因此如果沒有server_name這個字段,server是無法給與客戶端相應的數字證書的,Server_name擴展則允許服務器對瀏覽器的請求授予相對應的證書。

服務器回覆

(包括Server Hello,Certificate,Certificate Status)

服務器在收到client hello後,會回覆三個數據包,下面分別看一下:

4、Server Hello


4.1、我們得到了服務器的以Unix時間格式記錄的UTC和28字節的隨機數 (random_S)。

4.2、Seesion ID,服務端對於session ID一般會有三種選擇  (稍會兒我們會看到隔了半分鐘,第二次抓包就有這個Session ID):

(1)恢復的session ID:我們之前在client hello裏面已經提到,如果client hello裏面的session ID在服務端有緩存,服務端會嘗試恢復這個session;

(2)新的session ID:這裏又分兩種情況,第一種是client hello裏面的session ID是空值,此時服務端會給客戶端一個新的session ID,第二種是client hello裏面的session ID此服務器並沒有找到對應的緩存,此時也會回一個新的session ID給客戶端;

(3)NULL:服務端不希望此session被恢復,因此session ID爲空。


4.3、我們記得在client hello裏面,客戶端給出了多種加密族 Cipher,而在客戶端所提供的加密族中,服務端挑選了TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256”

(a)TLS爲協議,RSA爲密鑰交換的算法;

(b)AES_256_CBC是對稱加密算法(其中256是密鑰長度,CBC是分組方式);

(c)SHA是哈希的算法。

這就意味着服務端會使用ECDHE-RSA算法進行密鑰交換,通過AES_128_GCM對稱加密算法來加密數據,利用SHA256哈希算法來確保數據完整性。


5、Certificate


在前面的https原理研究中,我們知道爲了安全的將公鑰發給客戶端,服務端會把公鑰放入數字證書中併發給客戶端(數字證書可以自簽發,但是一般爲了保證安全會有一個專門的CA機構簽發),所以這個報文就是數字證書,4097 bytes就是證書的長度。

我們打開這個證書,可以看到證書的具體信息,這個具體信息通過抓包報文的方式不是太直觀,可以在瀏覽器上直接看。點擊chrome瀏覽器左上方的綠色鎖型按鈕) 

6、Server Hello Done

我們抓的包是將 Server Hello Done  和 server key exchage 合併的包:


7、客戶端驗證證書真僞性

客戶端驗證證書的合法性,如果驗證通過纔會進行後續通信,否則根據錯誤情況不同做出提示和操作,合法性驗證包括如下:

(1)證書鏈的可信性trusted certificate path,方法如前文所述;

(2)證書是否吊銷revocation,有兩類方式離線CRL與在線OCSP,不同的客戶端行爲會不同;

(3)有效期expiry date,證書是否在有效時間範圍;

(4)域名domain,覈查證書域名是否與當前的訪問域名匹配,匹配規則後續分析; 

8、祕鑰交換

這個過程非常複雜,大概總結一下:

(1)首先,客戶端利用CA數字證書實現身份認證,利用非對稱加密協商對稱密鑰。

(2)客戶端會向服務器傳輸一個“pubkey”隨機數,服務器收到之後,利用特定算法生成另外一個“pubkey”隨機數,客戶端利用這兩個“pubkey”隨機數生成一個 pre-master 隨機數。

(3)客戶端利用自己在 client hello 裏面傳輸的隨機數 random_C,以及收到的 server hello 裏面的隨機數 random_S,外加 pre-master 隨機數,利用對稱密鑰生成算法生成 對稱密鑰enc_key:enc_key=Fuc(random_C, random_S, Pre-Master)


9、生成session ticket


如果出於某種原因,對話中斷,就需要重新握手。爲了避免重新握手而造成的訪問效率低下,這時候引入了session ID的概念, session ID(以及session ticke)的思想很簡單,就是每一次對話都有一個編號(session ID)。如果對話中斷,下次重連的時候,只要客戶端給出這個編號,且服務器有這個編號的記錄,雙方就可以重新使用已有的“對話密鑰”,而不必重新生成一把。

因爲我們抓包的時候,是幾個小時內第一次訪問 https://www.baodu.com 首頁,因此,這裏並沒有 Session ID.稍會兒我們會看到隔了半分鐘,第二次抓包就有這個Session ID) 

session ID是目前所有瀏覽器都支持的方法,但是它的缺點在於session ID往往只保留在一臺服務器上。所以,如果客戶端的請求發到另一臺服務器,就無法恢復對話。session ticket就是爲了解決這個問題而誕生的,目前只有Firefox和Chrome瀏覽器支持。

後續建立新的https會話,就可以利用 session ID 或者 session Tickets , 對稱祕鑰可以再次使用,從而免去了 https 公私鑰交換、CA認證等等過程,極大地縮短 https 會話連接時間。

10、利用對稱祕鑰傳輸數據

三、半分鐘後,再次訪問百度:

有這些大的不同:



由於服務器和瀏覽器緩存了 Session ID 和 Session Tickets,不需要再進行 公鑰證書傳遞,CA認證,生成 對稱密鑰等過程,直接利用半分鐘前的對稱密鑰加解密數據進行會話。

1、Client Hello



2、Server Hello



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章