HTTPS 筆記
主要記錄學習工作流程的筆記
資料
- ofollow,noindex">Http基礎知識學習(四),瞭解HTTPS
- 通俗理解數字簽名,數字證書和https
- https原理通俗瞭解
- SSL Handshake and HTTPS Bindings on IIS
- SSL/TLS協議詳解,共有4篇
- 說人話的 HTTPS 協議簡述——揭祕 Handshake 過程
可以按照先後順序看下
1. 握手前須知
HTTP + 加密 + 認證 + 完整性保護 = HTTPS
HTTPS = HTTP + TLS/SSL
, TLS
是 SSL
的後繼版本,現在一般都用 TLS
SSL
是一個二進位制協議,通過 443埠
進行流量傳輸
為了安全傳輸需要對傳輸內容進行加密,為了解決各種 雞生蛋蛋生雞
的問題, HTTPS
中使用對稱加密對傳輸內容進行加密,使用非對稱加密來對對稱加密的金鑰加密
為了防止非對稱加密技術的公鑰被掉包替換,需要 數字證書
來保證公鑰的安全性,但由於一個機構要頒發很多證書,為了防止證書被篡改,使用 數字簽名
技術來驗證數字證書
可以看看 https原理通俗瞭解
數字證書 CA
- 證明公開金鑰本身就是貨真價實的公開金鑰。
- 證明目標網站是經過 CA 驗證的可信任網站
主要包含:
- 物件名稱,人、伺服器、組織等
- 過期時間
- 證書釋出者,由誰為證書擔保
- 來自證書釋出者的數字簽名

數字證書
圖來自 《HTTP 權威指南》
注意:證書自身也有公鑰,伺服器也有公鑰,證書的公鑰為了數字簽名,伺服器的公鑰為了交換對稱演算法金鑰
數字簽名
驗證報文未被偽造或篡改
使用加密系統對報文進行簽名,可以說明報文的來源,同時又可以驗證報文的完整性
數字簽名通常是使用非對稱加密技術產生。由於私鑰只有所有者知道,可以將私鑰作為 指紋
使用
通過數字簽名驗證證書

通過數字簽名驗證證書
圖來自 SSL/TLS協議詳解,共有4篇
驗證數字證書,解決同一機構頒發的不同證書被篡改問題。類比畢業證的編號
在服務端,根據一個 Hash
演算法計算一個證書 Hash
值,使用證書的私鑰進行加密,也就是簽名。客戶端拿到證書後,先使用證書公鑰對簽名進行解密得到一個 Hash_1
,然後再次使用證書公鑰根據指定的演算法對證書進行計算,得到 Hash_2
,比較兩個 Hash
值,相同則認證通過認為證書有效
通過數字簽名驗證報文完整性

驗證報文
- 節點
A
提取變長報文為定長摘要 - 節點
A
以使用者私鑰為引數使用一個簽名函式對摘要進行計算。計算出簽名後,節點A
附加在報文末端,之後將報文和簽名發給B
- 節點
B
接收到使用私鑰加密後的簽名,使用公鑰的反函式,得到摘要資訊,之後比較摘要版本資訊
在 RSA
的加密系統中,解碼函式 D
已包含私鑰,可以作用簽名函式使用
若摘要版本資訊不匹配,說明報文被篡改或者傳送報文的一端就不是真實的節點 A
2. 握手流程
在整個 Handshake
過程中,需要完成:
- 交換協議版本號
- 選擇一個兩端都能使用的密碼
- 對兩端身份進行驗證
- 生成臨時會話金鑰,以便加密通道
在最終生成的 會話金鑰
是臨時生成的,這樣也保證了 前向安全
- 單向認證握手流程

SSL_Handshak
圖來自 SSL Handshake and HTTPS Bindings on IIS
會話發起時,先進行 TCP
的3次握手,成功建立連線後,進行 TLS
的握手
可以通過 Wireshake
對 GitHub
進行抓包,幫助理解學習

GitHub.com 使用 Wireshake 抓包
2.1 第一步,Client Hello

第1步,Client Hello
圖來自 ,Van Bruce大佬的小專欄 說人話的 HTTPS 協議簡述——揭祕 Handshake 過程
握手第一步,客戶端傳送 Hello報文
Client
生成一個 cRandrom_1
,客戶端將 cRandrom_1
以及 TLS
版本,自己支援的加密套件列表, 會話 id
等資訊傳送給服務端
cRandrom_1 在生成最終的臨時會話金鑰時會用到
隨機數是一個 32
位元組的資料。前 4
個位元組表示 epoch
格式的日期,紀元時間是自 1970年1月1日
以來的秒數,後 28
個位元組就是由加密強隨機數生成器生成的隨機數
資料是明文傳送
使用 Wireshark
通過 Chrome
對 Github
進行抓包,過濾捕獲

GitHub, Client Helllo
TLS
版本是 1.2
Random
就代表著客戶端生成的 cRandrodm_1
資料
第一次進行 TLS
握手, Session ID
為空
支援的加密套件列表中有 19
個
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
表示:
使用 ECDHE
演算法交換金鑰, RSA
進行簽名或者公鑰驗證身份, AES_128_GCM
加密傳輸資料, SHA256
來驗證資料完整性
ECDHE
是 ECDH
的繼生版本,支援 前向安全性
,也就是生成的是臨時的金鑰。 ECDH
是基於橢圓曲線的加密演算法
ECDH
和 DH
演算法的目的都是用於 交換金鑰而不是加解密 ,但 ECDH
比 DH
破解難度更大
關於金鑰交換,可以看看 SSL/TLS協議詳解(上):密碼套件,雜湊,加密,金鑰交換演算法 瞭解下
AES_128_GCM
稱為批量加密演算法,這裡表示 AES
是一個常用的對稱加密演算法,金鑰長度為 128
,採用 GCM
模式
AES
是 塊密碼 ,也就是對輸入的純文字用固定長度的塊來進行加密,加密後的每個塊按再順序傳送,最後按類似的方式來進行解密
關於這些加密演算法,目前只求個面熟,瞭解下目的
2.2 第二步,Server Hello

第2步,Server Hello
當服務端收到 Client Hello
後,必須要傳送 Server Hello
資訊
伺服器先進行檢查 TLS
版本,以及客戶端演算法的條件
如果伺服器能接受並支援所有條件,將會發送證書及其他資訊;否則,伺服器會發送握手失敗資訊
過程中,服務端會生成 第二個隨機數 sRandrom_2
,並確認出具體的加密方法,這些資訊在下一步會隨證書一起發給客戶端
伺服器生成的 sRandrom_2
也是 32
位元組,但前 4
位元組表示伺服器的 Unix
紀元時間
證書中包含有 伺服器的公鑰
這一步中, 資料也是明文的
所有的伺服器都不會在這一步傳送證書

GitHub , ServerHelllo
伺服器響應 0x0303
表示伺服器同意使用 TLS 1.2
伺服器端這時已經確定併發送給了客戶端具體的加密套件
伺服器端會生成 Session id
,傳送給客戶端後,客戶端會寫入約定的引數到此 Session id
,並給定過期時間
再次發起會話時,客戶端將在 Client Hello
中包含此 Session id
若客戶端在到期時間之前再次連線到伺服器,則伺服器可以檢查 Session id
對應的快取引數,並重用它們而無需完全握手
Cipher suite
是兩端約定好的加密演算法
2.3 第三步,服務端傳送證書,並進行伺服器金鑰交換(可選)
伺服器金鑰交換(Server Key Exchange)是可選的, GitHub.com
中,有這個操作,這和 GitHub
支援的密碼套件有關

GitHub 第三步抓包
2.3.1 Certificate 證書資訊
進行完成第二步,伺服器會先進行 Certificate
握手,也就是向客戶端傳送證書
通過抓包,證書訊息共 3078
位元組,這是 GitHub.com
所有伺服器資訊的證書。伺服器按信任鏈的順序傳送完整的證書列表
該鏈中的第一個是伺服器證書,接著是頒發伺服器證書的 intermediate CA
的證書,然後是下一個 intermediate CA
的證書......直到 Root CA
的證書。伺服器不可以傳送 Root CA
證書,因為在大多數情況下,瀏覽器可以從任何 intermediate CA
識別 Root CA
對於 GitHub
來說,使用 SHA256
來生成 Hash
值, RSA
用於簽名
2.3.2 伺服器金鑰交換 Server Key Exchange
為什麼 GitHub 必須要這一步驟?
在第二步, GitHub
選擇的 Session
的密碼套件是 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
客戶端和伺服器端使用 ECDHE(Elliptic Curve Diffie Hellman)
來進行交換金鑰,由於在 DH(Diffie-Hellman)
中,客戶端無法自行計算生成 預主金鑰(Pre-master secret)
,需要從服務端獲取 DH
的公鑰,伺服器便單獨在這個握手中傳送公鑰
伺服器金鑰交換完成之後,再發送一個 Server Helloe Done
訊息進行通知,客戶端接到後開始準備計算 Pre-Master Secret
2.4 第四步,客戶端證書驗證,金鑰交換,向伺服器傳送測試加密資料

第4步,生成Pre-Master Secret
接到服務端證書後,客戶端先根據證書攜帶的資訊對證書進行驗證,證書驗證通過後,客戶端再生成第三個隨機數 cRandrom_3
,這個隨機數做為 預主金鑰(Pre-Master Secret)
到了此時,兩端一共產生了 3
個隨機數,這個時候客戶端知道 cRandrom_1,sRandRom_2
以及用來做為 Pre-Master Secret
的 cRandrom_3
,但伺服器端此時還不知道 cRandrom_3
為了讓伺服器端也知道 Pre-Master Secret
,需要先進行 金鑰交換
看下 GitHub.com
握手情況

GitHub.com,第4步
2.4.1 金鑰交換
客戶端進行金鑰交換時,根據約定 RSA
及 DH類
演算法分兩種情況
RSA是直接加密 Pre-Master Sercet 後傳送到服務端,DH類是需要以 Pre-Master Sercet 為引數進行計算,傳遞的是客戶端生成 Pre-Master Sercet 的共享公鑰
若兩端 問候(Hello)
階段約定好的是用 RSA
進行交換金鑰,伺服器端已有對應的私鑰,客服端在接到證書後,隨機生成 48
位元組的 Pre-Master Sercet
,之後使用伺服器端的公鑰對 Pre-Master Sercet
加密,傳送到服務端
若約定好的是 DH類
演算法,像 DHE,ECDHE
和 RSA
不同, DH類
演算法並非加解密演算法,是 金鑰協商演算法
GitHub.com
使用的是 ECDHE
來進行交換金鑰,服務端在第 3
步的 Server Key Exchange
握手前計算生成了伺服器端的 公-私
金鑰對,並把公鑰在 Server Key Exchange
握手階段,傳送給客戶端,通知客戶端後面需要進行私鑰交換
客戶端接收到伺服器端的公鑰後,使用自身的 公-私
鑰,以 Pre-Master Sercet
為引數進行計算,得到一個 共享金鑰
,然後在 Client Key Exchange
傳送給服務端
客戶端自身也會通過 cRandrom_1 + sRandrom_2 + PreMaster Sercet
計算 Master Sercet
,但 Master Sercet還不是最終用來加密的對稱金鑰
得到 Master Sercet
後,再經過一系列複雜計算後,最終生成用於對稱加密的 Session Key
, SessionKey 是一組隨機數
ECDHE演算法流程文字描述如下:
- 客戶端隨機生成隨機值Ra,計算Pa(x, y) = Ra * Q(x, y),Q(x, y)為全世界公認的某個橢圓曲線演算法的基點。將Pa(x, y)傳送至伺服器
- 伺服器隨機生成隨機值Rb,計算Pb(x,y) - Rb * Q(x, y)。將Pb(x, y)傳送至客戶端
- 客戶端計算Sa(x, y) = Ra * Pb(x, y);伺服器計算Sb(x, y) = Rb *Pa(x, y)
- 演算法保證了Sa = Sb = S,提取其中的S的x向量作為金鑰(預主金鑰)
2.4.2 Change Cipher Spec,Encrypted_Handshake_Message
當客戶端傳送了共享金鑰後,計算出加密用的對稱金鑰後,客戶端傳送 Change Cipher Spec
握手訊息通知伺服器之後的訊息都是加密的
接著,客戶端便根據之前所有握手訊息的資訊,計算出一個 Hash
值,並使用協商出的加密演算法加密,傳送給服務端
2.5 第五步,伺服器還原 Premaster Secret,並回復加密測試驗證訊息

第5步,伺服器還原 Premaster Sercet
伺服器根據演算法,還原出 Premaster Secret
,這時伺服器也擁有了 cRandrom_1 + sRandrom_2 + PreMaster Sercet
,也可以根據協商,計算出最終的對稱加密用 Session key
注意:在計算得到 Master Sercet 後,客戶端和服務端都會刪除各自的私鑰

GitHub.com 握手第5步
同客戶端一樣,完成一系列操作,生成 Session key
後,計算出之前所有握手訊息的 Hash
值,並將客服端發來的加密資訊解密出來,進行比對校驗,驗證金鑰和資料的正確性
驗證通過後,服務端結合當前所有握手訊息的資訊計算 Hash
值,再使用自己生成的對稱金鑰加密,傳送給客戶端
當客戶端接收到服務端的 Encrypted_Handshake_Message
後,對金鑰和資料校驗通過時,意味著握手階段結束,之後便是進行加密通訊

加密通訊
大致的握手流程就是這些
3. 補充
本篇中是以GitHub來抓包幫助學習的,是單向認證
證書是靜態的,為了保證金鑰的隨機,加入 Pre Master Sercet
做為一種隨機因子。然而單單一個 Pre Master Sercet
還不足以 完全隨機
,採用 cRandrom_1 + sRandrom_2 + PreMaster Sercet
三個隨機數來使金鑰更加隨機,更難暴力破解
在整個握手過程中,最終加密用到的對稱金鑰是不會在兩端進行傳輸的。傳輸的只是 3
個隨機數,其中前兩個隨機數是明文傳輸,而最後一個是加密傳輸的
在計算出 Master Sercet
後,會將兩端各自的私鑰進行刪除
關於會話快取過程,可以看看 HTTPS協議詳解(四):TLS/SSL握手過程
再看下,整個握手流程

整個握手流程
4. 最後
很多地方還不懂,先把了解的記錄下,這次的學習瞭解收穫還是挺多的。 Wireshake
這個軟體也剛學會一點,以後多用用,能幫助理解
應該會有很多錯誤的地方,希望比較熟悉 HTTPS
的同學,指出來