HTTPS加密原理:
- 地址為綠色, 表示使用了加密傳輸,安全且可信任;
- 地址為紅色, 則表示雖然開啟了加密, 但網站身份未驗證, 不保證中間不會被人篡改。
從我們在地址欄敲下 https:// 網站那一剎那, 到內容顯示到我們面前, 中間經過了哪些過程了? 瀏覽器根據什么來判斷, 當前網站網址是安全的還是未驗證的?
互聯網外交安全策略SSL/TLS協議運行機制。
一.Https背景介紹:SSL/TLS協議的由來
最早期的通信是不使用SSL/TLS的HTTP通信,也就是沒有加密的通信。信息傳遞過程中存在很多的問題:被第三方竊聽,被第三方修改通信內容,被第三方冒充他人身份參與通信。 大家都希望能有一種加密的信息傳輸,能夠保證信息安全,SSL/TLS協議誕生。
歷史發展
互聯網加密通信協議的歷史,幾乎與互聯網一樣長:
1994年,NetScape公司(網景公司)設計了SSL 1.0版,但是未發布;
1995年,NetScape公司發布SSL 2.0版,很快發現有嚴重漏洞;
1996年,SSL 3.0版問世,得到大規模應用;
1999年,互聯網工程任務組(IETF)標准化了一種名為 TLS 1.0 的新協議,這是SSL的升級版本;
2006年和2008年,TLS兩次升級,分別更新至TLS 1.1和TLS 1.2(修復了1.1中的漏洞)。緊接着2011年發布了TLS 1.2的修訂版;
然而直到2013年大部分的瀏覽器才開始支持TLS 1.2。
2018.8 ,TLS 1.3的最終版本發布,包含許多安全性和性能改進。
由此可見,SSL和TLS簡單地可以理解為是同一種協議的不同版本,故它們總是成對出現。
TLS 1.3於2018.3月發布,你的瀏覽器應該已經支持它了。
TLS 1.3進一步改進了安全性,移除了一些不安全的特性。
- 實際上現代的瀏覽器已經基本不使用SSL,使用的都是TLS, SSL 3.0於2015年已經壽終正寢 —— 各大瀏覽器也不支持了。但是由於SSL這個術語存在的時間太長,很多地方還是廣泛的使用它,但是要清楚其實它說的是TLS。
- 有調查顯示現在絕大部分瀏覽器(> 99.5%)都使用TLS 1.2或者TLS 1.3。只有不足1%的瀏覽器仍然使用TLS 1.0或者TLS 1.1。
- TLS 1.2仍然是主流協議(本文寫於2020年初),相信將來逐漸TLS 1.3將會作為主流協議。
- 很多瀏覽器將會開始不支持TLS 1.0和1.1:
- Google將在Chrome 72中不推薦使用TLS 1.0和1.1,而Chrome 81之后將會完全不支持。
- Mozilla的Firefox,微軟的Edge和IE以及蘋果的Safari 都會分別於2020年逐漸移除對TLS 1.0和1.1的支持。
- 那么一些還在使用TLS 1.0和1.1的網站就得被迫升級到TLS 1.2或者TLS 1.3。
- 要關閉瀏覽器對TLS 1.0和1.1的支持,可以在Internet選項中修改:

SSL/TLS在TCP/IP參考模型中的位置
SSL/TLS其實是一個協議族 而非單個協議,由SSL/TLS握手協議、修改密文協議、報警協議以及記錄協議四部分組成。
SSL/TLS協議自身可分為兩層:主要的有SSL記錄協議和SSL握手協議。
SSL記錄協議建立在可靠的傳輸協議,如TCP之上,為高層協議提供數據封裝、壓縮、加密等基本功能的支持。
SSL握手協議建立在SSL記錄協議之上,用於在實際的數據傳輸開始前,通信雙方進行身份認證、協商交換密鑰等。

SSL/TLS如何實現安全保障呢
使用SSL/TLS協議,能夠使我們在互聯網上的通信做到“看不懂、改不掉、仿不了”,這組安全協議真的很復雜!分別對信息安全的機密性、完整性和可認證性做了確認。
機密性:當通信雙方確信沒有人能夠理解他們的對話內容時,通信被認為是保密的。使用對稱加密可以實現通信的機密性。
完整性:SSL/TLS具有校驗機制,握手協議中定義了MAC,一旦信息被篡改,通信雙方會立即發現並采取措施。
可認證性:為防止惡意攻擊者冒充合法網站,網站需要通過證書和公鑰加密來向Web瀏覽器證明自己的身份,在此過程中,瀏覽器需要兩件事情來信任證書:證明另一方是證書的持有者,並證明證書是可信的。
在互聯網通信中,通過建立共享密鑰和證明證書的所有權的過程來實現機密性和可認證性,SSL/TLS協議則是通過“握手”流程來實現這兩點,當中的完整性是由握手協議定義的MAC來實現。那么,如此至關重要的“握手”流程是怎么樣的呢?
詳解“握手”流程
"握手階段"涉及四次通信 , 我們一個個來看。 需要注意的是,"握手階段"的所有通信都是明文的。

客戶端發出請求(ClientHello):
客戶端向服務器發出請求,會帶上以下信息:
- 一個客戶端生成的隨機數
- 支持的加密方式,即圖中的Cipher Suite
- 支持SSL/TLS協議的版本號
- Session ID,如果是之前斷開的會話,會帶上Session ID用來恢復會話。
- 簽名使用的哈希算法
服務器回應(SeverHello):
服務器響應客戶端的請求,如果上一步帶上了Session ID,則直接恢復會話,否則帶上以下信息給客戶端:
- 選擇SSL/TLS協議版本號
- 選擇加密方式
- 一個服務器生成的隨機數
- 服務器證書
客戶端會在這里校驗服務器證書的合法性,包括檢測證書有效時間,以及證書中域名與當前會話域名是否匹配,並沿着信任鏈查找頂層證書頒發者是否是操作系統信任的CA機構。
客戶端回應:
客戶端校驗服務器證書的合法性,生成premaster secret,向服務器發送以下信息:
- 用服務器證書取出的公鑰加密后的premaster secret,這里的premaster secret其實是另一個隨機數
- 加密約定改變通知,通知服務器,以后的通信都適用協商好的加密方法和密鑰進行加密
- 客戶端握手結束通知。這個報文也是驗證消息,是前面發送的所有內容的哈希值,用來供服務器校驗。

服務器最后確認:
這是握手過程的最后一步,服務器會把以下信息發送給客戶端:
- 加密約定改變通知,通知客戶端,以后的通信都適用協商好的加密方法和密鑰進行加密
- 服務器握手結束通知,該報文也作為校驗消息,供客戶端驗證。
到這個時候,客戶端和服務器同時擁有了3個隨機數,使用這三個隨機數生成的密鑰,將被用於后續通信的對稱加密。
二、證書(Digital certificate)
理解 HTTPS 的工作原理:
HTTPS,也稱作HTTP over TLS。 TLS的前身是SSL,TLS 1.0通常被標示為SSL 3.1,TLS 1.1為SSL 3.2,TLS 1.2為SSL 3.3。 本文着重描述TLS協議的1.2版本。
下圖描述了在TCP/IP協議棧中TLS(各子協議)和HTTP的關系

Credit: Kaushal Kumar Panday From: SSL Handshake and HTTPS Bindings on IIS
其中 SSL Handshaking Protocols 包括 Handshake protocol,Change Ciper Spec protocol 和Alert protocol組成了。
HTTPS和HTTP協議相比提供了
- 數據完整性:內容傳輸經過完整性校驗
- 數據隱私性:內容經過對稱加密,每個連接生成一個唯一的加密密鑰
- 身份認證:第三方無法偽造 服務端(客戶端)身份
其中, 數據完整性和隱私性由 TLS Record Protocol保證, 身份認證由TLS Handshaking Protocols實現。
總覽:使用RSA算法的SSL握手過程是這樣的:

Source: Keyless SSL: The Nitty Gritty Technical Details
- [明文] 客戶端發送隨機數client_random和支持的加密方式列表
- [明文] 服務器返回隨機數server_random,選擇的加密方式和服務器證書鏈
- [RSA] 客戶端驗證服務器證書,使用證書中的公鑰加密premaster secret發送給服務端
- 服務端使用私鑰解密premaster secret
- 兩端分別通過client_random,server_random和premaster secret生成master secret,用於對稱加密后續通信內容
那么什么是證書呢?

證書中包含什么信息:
- 證書信息: 過期時間和序列號
- 所有者信息:姓名等
- 所有者公鑰
2.1、為什么服務端要發送證書給客戶端?
互聯網有太多的服務需要使用證書來驗證身份,以至於客戶端(操作系統或瀏覽器等)無法內置所有證書,需要通過服務端將證書發送給客戶端。
2.2、客戶端為什么要驗證接收到的證書?
中間人攻擊
客戶端<------------攻擊者<------------服務端
偽造證書 攔截請求
2.3、客戶端如何驗證接收到的證書?
為了回答這個問題,需要引入數字簽名(Digital Signature)。
+---------------------+
| A digital signature |
|(not to be confused |
|with a digital |
|certificate) | +---------+ +--------+
| is a mathematical |----哈希--->| 消息摘要 |---私鑰加密--->| 數字簽名 |
|technique used | +---------+ +--------+
|to validate the |
|authenticity and |
|integrity of a |
|message, software |
|or digital document. |
+---------------------+
將一段文本通過哈希(hash)和私鑰加密處理后生成數字簽名。
假設消息傳遞在Bob,Susan和Pat三人之間發生。Susan將消息連同數字簽名一起發送給Bob,Bob接收到消息后,可以這樣驗證接收到的消息就是Susan發送的
+---------------------+
| A digital signature |
|(not to be confused |
|with a digital |
|certificate) | +---------+
| is a mathematical |----哈希--->| 消息摘要 |
|technique used | +---------+
|to validate the | |
|authenticity and | |
|integrity of a | |
|message, software | 對
|or digital document. | 比
+---------------------+ |
|
|
+--------+ +---------+
| 數字簽名 |---公鑰解密--->| 消息摘要 |
+--------+ +---------+
當然,這個前提是Bob知道Susan的公鑰。更重要的是,和消息本身一樣,公鑰不能在不安全的網絡中直接發送給Bob。
此時就引入了證書頒發機構(Certificate Authority,CA),CA數量並不多,Bob客戶端內置了所有受信任CA的證書。CA對Susan的公鑰(和其他信息)數字簽名后生成證書。
Susan將證書發送給Bob后,Bob通過CA證書的公鑰驗證證書簽名。
Bob信任CA,CA信任Susan 使得 Bob信任Susan,信任鏈(Chain Of Trust)就是這樣形成的。
事實上,Bob客戶端內置的是CA的根證書(Root Certificate),HTTPS協議中服務器會發送 證書鏈(Certificate Chain)給客戶端。
TLS協議:
TLS協議包括 TLS Record Protocol 和 TLS Handshake Protocol。總覽中的流程圖僅涉及到TLS Handshake Protocol。
TLS Record Protocol:
在TLS協議中,有四種子協議運行於Record protocol之上
- Handshake protocol
- Alert protocol
- Change cipher spec protocol
- Application data protocol
Record protocol起到了這樣的作用
- 在發送端:將數據(Record)分段,壓縮,增加MAC(Message Authentication Code)和加密
- 在接收端:將數據(Record)解密,驗證MAC,解壓並重組
值得一提的是,Record protocol提供了數據完整性和隱私性保證,但Record類型(type)和長度(length)是公開傳輸的。
Record Protocol有三個連接狀態(Connection State),連接狀態定義了壓縮,加密和MAC算法。所有的Record都是被當前狀態(Current State)確定的算法處理的。
TLS Handshake Protocol和Change Ciper Spec Protocol會導致Record Protocol狀態切換。
empty state -------------------> pending state ------------------> current state
Handshake Protocol Change Cipher Spec
初始當前狀態(Current State)沒有指定加密,壓縮和MAC算法,因而在完成TLS Handshaking Protocols一系列動作之前,客戶端和服務端的數據都是明文傳輸的;當TLS完成握手過程后,客戶端和服務端確定了加密,壓縮和MAC算法及其參數,數據(Record)會通過指定算法處理。
其中,Record首先被加密,然后添加MAC(message authentication code)以保證數據完整性。
TLS Handshaking Protocols:
Handshakeing protocols 包括Alert Protocol,Change Ciper Spec Protocol和Handshake protocol。本文不會詳細介紹Alert Protocol和Change Ciper Spec Protocol。
使用 RSA算法的握手過程是這樣的(已在總覽中提到)

Source: Keyless SSL: The Nitty Gritty Technical Details
客戶端和服務端在握手hello消息中明文交換了client_random和server_random,使用RSA公鑰加密傳輸premaster secret,最后通過算法,客戶端和服務端分別計算master secret。 其中,不直接使用premaster secret的原因是:保證secret的隨機性不受任意一方的影響。
Diffie–Hellman算法的原理: 除了使用RSA算法在公共信道交換密鑰,還可以 通過Diffie–Hellman算法。 Diffie–Hellman算法的原理是這樣的:

By Original schema: A.J. Han Vinck, University of Duisburg-Essen SVG version: Flugaal [Public domain], via Wikimedia Commons
使用Diffie–Hellman算法 交換premaster secret的流程

Source: Keyless SSL: The Nitty Gritty Technical Details
小結:
TLS Handshaking Protocols 協商了TLS Record Protocol使用的算法和所需參數,並驗證了服務端身份;TLS Record Protocol在協商后保證應用層數據的完整性和隱私性。
TLS Handshaking Protocol的核心是在公開信道上傳遞premaster secret。
Q&A
1.為什么傳輸內容不直接使用非對稱加密?
性能
2.HTTPS能保證正常連接?
no
There are a number of ways in which a man-in-the-middle attacker can attempt to make two entities drop down to the least secure method they support.
攻擊者甚至可以直接丟棄雙方的數據包。
3.服務端如何驗證客戶端身份?
通過Client Certificate
This message conveys the client’s certificate chain to the server; the server will use it when verifying the CertificateVerify message (when the client authentication is based on signing) or calculating thepremaster secret (for non-ephemeral Diffie- Hellman). The certificate MUST be appropriate for the negotiated cipher suite’s key exchange algorithm, and any negotiated extensions.
4.Alert protocol有什么作用?
Closure Alerts:防止Truncation Attack
In a truncation attack, an attacker inserts into a message a TCP code indicating the message has finished, thus preventing the recipient picking up the rest of the message. To prevent this, SSL from version v3 onward has a closing handshake, so the recipient knows the message has not ended until this has been performed.
Error Alerts:錯誤處理
master secret是如何計算的
master_secret = PRF(pre_master_secret, "master secret",
ClientHello.random + ServerHello.random)
[0..47];
加密,壓縮和MAC算法參數是如何計算的
Handshaking Protocols使得客戶端和服務端交換了三個參數:client_random,server_random和master_secret,通過以下算法生成算法所需要的參數
To generate the key material, compute
key_block = PRF(SecurityParameters.master_secret,
"key expansion",
SecurityParameters.`server_random ` +
SecurityParameters.`client_random`);
until enough output has been generated. Then, the key_block is
partitioned as follows:
client_write_MAC_key[SecurityParameters.mac_key_length]
server_write_MAC_key[SecurityParameters.mac_key_length]
client_write_key[SecurityParameters.enc_key_length]
server_write_key[SecurityParameters.enc_key_length]
client_write_IV[SecurityParameters.fixed_iv_length]
server_write_IV[SecurityParameters.fixed_iv_length]
The master secret is expanded into a sequence of secure bytes, which is then split to a client write MAC key, a server write MAC key, a client write encryption key, and a server write encryption key
使用Diffie-Hellman算法的TLS握手細節

十、題外話
1.如何保證公鑰屬於被訪問的合法網站?
將公鑰放在數字證書中,簽發證書的CA是被信任的,故公鑰是被信任的。
2.為什么要這么復雜地產生會話密鑰,何不直接傳輸商定好的密鑰更方便?
隨着攻擊手段的不斷發展,任何傳輸過程都不受信任,即使將會話密鑰進行加密傳輸,都有被竊取的危險。因此采用Diffle-Hellman密鑰協商算法,在傳輸過程中能夠始終不出現會話密鑰本身,會話密鑰僅在握手結束時在客戶端和服務器本地各自生成。
3.既然產生對稱的會話密鑰很復雜,為什么不采用可避免密鑰泄露問題的公鑰加密?
因為公鑰加密相比於對稱加密,計算速度很慢,不適用於通信時的大量數據加密。
4.在握手過程中如何確認服務器是私鑰持有者?
客戶端無法看見服務器的私鑰,那就讓服務器證明它可以使用私鑰即可,服務器使用私鑰對客戶端已知的信息進行數字簽名,若客戶端能夠用服務器的公鑰認證該數字簽名,則可確定對方持有相應私鑰。