SSL/TLS
- 一、SSL/TLS
- 1.1 歷史發展
- 1.2 使用場景
- 1.3 解決的問題
- 1.4 作業流程
- 二、對稱加密(Symmetric Cryptography)
- 2.1 作業原理
- 2.2 翻轉攻擊
- 2.3 認證加密(Authentication Encryption)
- 2.4 Diffie-Hellman
- 2.5 KDF
- 2.6 Diffie-Hellman安全性
- Trapdoor function
- Static Key
- Ephemeral Key
- 三、非對稱加密(Asymmetric cryptography)
- 3.1 作業原理
- 3.2 如何分享公鑰
- 3.3 數字證書的獲取
- 3.4 CA鏈
- 3.5 數字證書的簽名與驗證
- 四、TLS 1.3 握手流程
- 4.1 完整的握手流程
- 4.2 預共享密鑰
- 4.3 0-RTT
你可以帶著以下目的進行學習:
- TLS Handshake握手發生了什么?
- 為什么需要握手?
- TLS使用什么加密演算法來保護資料?
- 為什么我們需要數字證書?
- 為什么需要由證書頒發機構簽名?
- 什么是數字簽名,如何生成?
一、SSL/TLS
SSL:安全套接字層(Secure Socket Layer),是TLS的前身,
TLS:安全傳輸層協議的簡稱(Transport Layer Security),
1.1 歷史發展

歷史發展時間線如上圖所示,
1995年由Netscape發布 SSL 2.0
1996年由Netscape發布 SSL 3.0
1999年由IETF在RFC 2246中首次定義 TLS 1.0,作為SSL 3.0的升級
2006年由IETF在RFC 4346發布 TLS 1.1
2008年由IETF在RFC 5246發布 TLS 1.2
2018年由IETF在RFC 8446發布 TLS 1.3
2011年棄用 SSL 2.0
2015年棄用 SSL 3.0
2020年棄用 TLS 1.0 與 TLS 1.1
截至2020年,只有TLS 1.2和TLS 1.3仍然有效,
1.2 使用場景
舉三個生活中常用的示例:
- 網站 HTTPS 協議(HTTPS = HTTP + TLS)
- 郵箱 SMTPS 協議(SMTPS = SMTP + TLS)
- 安全檔案傳輸 FTPS 協議(FTPS = FTP + TLS)
1.3 解決的問題
TLS 為我們解決了 3 件事:
- 認證(Authentication):TLS借助非對稱密碼學驗證通信方的身份,這里指客戶端與服務器,以此保證我們將訪問真實的網站,而不是假網站,
- 保密(Confidentiality):TLS通過使用對稱加密演算法對訊息加密,保護交換的資料免受未經授權的訪問,
- 誠信(Integrity):TLS通過檢查訊息驗證碼識別傳輸期間的任何資料更改,
1.4 作業流程

如上圖所示,TLS作業流程由2個階段(或2個協議)組成:
1、握手協議(Handshake protocol),其主要目的是進行身份驗證和密鑰交換,該階段主要涉及以下步驟:
- 協商 TLS 協議版本,
- 選擇密碼演算法或密碼套件,
- 通過非對稱密鑰相互認證,
- 建立一個將用于下一階段的共享密鑰(對稱加密密鑰),
2、記錄協議(Record protocol),其主要目的是確保訊息傳輸的機密性和完整性,該階段主要涉及以下步驟:
- 使用握手中建立的共享密鑰對發出的訊息進行加密,
- 將加密后的訊息傳輸到另一側,
- 驗證訊息是否在傳輸程序中進行了修改,
- 使用握手中建立的共享密鑰對接收的訊息進行解密,
由于客戶端與服務器大量的資料加解密交換發生在記錄協議階段,故又因該階段解密資料量很大,又稱該階段為批量加密,
可以看出,TLS在整個流程中同時使用了對稱和非對稱加密兩種方式,那為什么不只使用一個?
- 對稱密鑰無法提供身份驗證,對稱密鑰使得客戶端和服務器之間共享一個相同的密鑰,故他們彼此之間一無所知,而由于彼此之間不知道對方身份,故無法保證密鑰的不泄露,
- 其實非對稱加密都能滿足以上需求,但是它比對稱加密要慢很多,所謂“很多”,是指速度降低100倍至10000倍,因此,它顯然不適用于批量加密,
在介紹SSL/TLS的完整握手流程之前,我們先了解下對稱加密與非對稱加密的相關內容,關于SSL/TLS的完整握手流程將在第四個大標題中講解,
二、對稱加密(Symmetric Cryptography)
2.1 作業原理

(如上圖所示)首先,Alice有一條純文本訊息,她想發送給Bob,但不希望互聯網中的任何人都可以閱讀,因此她使用他們之前彼此共享過的共享密鑰(Shared secret key)對訊息進行加密,然后通過互聯網將加密的訊息發送給Bob,Bob收到加密的訊息后,他可以輕松的使用相同的密鑰對其進行解密,由于該密鑰用于加密和解密,且加密和解密的程序是對稱的,故稱該程序為對稱加密程序,
似乎加密的資料就很安全?黑客仍然可以采用翻轉攻擊的方式破壞加密后的資料,
2.2 翻轉攻擊

(如上圖所示)現在,有一個可以在互聯網上捕獲他們交流資訊的黑客Harry,但是,該訊息已被加密,而Harry沒有密鑰,因此他將無法對其解密,但是他仍然可以改變訊息,通過一種稱為翻轉攻擊的技術,假設這一次,Alice不是在跟Bob通信,而是在和她的網上銀行通信,此時Alice想轉賬$100給某人,該訊息通過密鑰進行加密后通過互聯網發送給銀行,此時,Harry捕獲到了加密的訊息,雖然他無法解密,但是他可以將某些位從1翻轉為0,從0翻轉為1,然后將修改后的訊息轉發到銀行,當銀行解密后將獲得不同的訊息內容,在這種情況下,轉賬金額變成了$900而不是$100,因此非常危險,
那么,這就是需要我們在收到加密的資料后,有方法確保加密的訊息在傳輸程序中未被更改,該如何確保呢?使用認證加密,
2.3 認證加密(Authentication Encryption)
認證加密包括對訊息的加密和驗證程序,

(如上圖所示)該指示的是加密的程序,該程序可分為兩個步驟,其一是對訊息的加密,其二是為加密資訊生成訊息認證碼,
- 訊息的加密:Alice的訊息使用加密演算法(Encryption Algotithm)進行加密,例如AES-256-GCM或CHACHA20,該加密演算法同時會將共享密鑰、亂數與一個初始化向量(initialization vector)作為輸入,然后輸出加密后的內容(Encrypted message),
- 生成訊息認證碼:加密的內容、共享密鑰和亂數作為MAC(Message Authentication Code 訊息認證碼)演算法的輸入,若使用AES-256-GCM作為加密演算法,則認證演算法為GMAC;若使用CHACHA20為加密演算法,則認證演算法為POLY1305,此MAC演算法的作用類似于哈希函式,其輸出是一個訊息認證碼(ae6f21b),即MAC,該MAC將伴隨加密的內容一起發送給Bob,有時又稱MAC為一個認證標簽,

(如上圖所示)在TLS 1.3中,除了加密的訊息外,我們還想驗證一些關聯資料(Associated Data),例如地址(addresses)、埠(ports)、協議版本(protocol version)或序列號(sequence number),這些資訊是未加密,且通信雙方均知曉的 ,在TLS 1.3中,將這些關聯資料也作為MAC演算法的輸入,因此,整個程序又稱為帶有關聯資料的認證加密(Authenticated Encryption with Associated Data,簡稱AEAD)
接下來我們將看到Bob如何驗證加密的訊息在傳輸程序中是否被更改,

(如上圖所示)這是一個加密的反向程序,
從帶有MAC的加密訊息開始,我們將從加密的訊息中經過提取(Untag)程序,獲的MAC(ae6f21b)和不帶有MAC的加密訊息,然后,加密的訊息、共享密鑰、亂數(注意該亂數和加密程序中的亂數相同,在將訊息發送給對方時,會將亂數填充到加密的訊息中)以及關聯資料作為MAC演算法的輸入,然后輸出一個新的MAC值,現在,Bob可以簡單地比較兩個MAC值,如果它們不同,則表示加密的訊息已被更改,否則,他可以安全地解密內容,并充分相信這與Alice發送的訊息相同,
但是,Bob和Alice如何在不泄露給公眾的情況下實作共享密鑰的交換?

(如上圖所示)為此,他們需要使用一種能夠生成共享密鑰的密鑰建立協議,例如Diffie-Hellman Ephemeral(DHE)或Elliptic Curve Diffie-Hellman Ephemeral(ECDHE),
接下來我們了解下Diffie-Hellman在密鑰交換中的作業原理,
2.4 Diffie-Hellman

(如上圖所示)首先基數 g 和模數 p,這兩個數字是眾所周知的,且Bob和Alice都知曉這兩個數字,其次Bob和Alice都擁有一個私鑰,Alice的私鑰是 a,Bob的私鑰是 b,準備就緒后,現在開始進行密鑰交換:
- Alice通過私鑰 a 計算出她的公鑰A(通過如圖的公式),同理,Bob計算出他的公鑰 B,
- Bob將B發送給Alice,Alice將A發送給Bob,
- Alice通過收到的B,結合私鑰a和模數p計算出一個值S,此時Bob也由收到的A和自身的私鑰b及模數p計算出一個值,而該值正好也等于S,這兩個值神奇的相等!為什么?我們通過公式分解后可以發現他們的計算公式是相同的,
因此,Alice和Bob具有了相同的密鑰S,而沒有將其泄露給公眾,
但是請記住,不同加密演算法輸出的密鑰長度是不相同的,因此,Alice和Bob必須使用相同的密鑰派生函式制作密鑰,輸出相同長度的密鑰S,在TLS 1.3中,使用的密鑰派生函式是HMAC-based key derivation function,所以這是為什么命名HKDF的原因,
讓接下來我們將進一步了解密鑰派生函式作業原理,
2.5 KDF
密鑰派生函式(Key Derivation Function),簡稱KDF,

(如上圖所示)通常,KDF需要五個輸入引數:
- 密鑰內容(input key material,簡稱IKM),在我們的示例中,IKM是字母S,
- 需要輸出密鑰的長度(Key Length),例如128位,
- 加密哈希函式(Hash Function),例如HMAC-SHA256,
- 可選資訊(Optional Info),例如背景關系(context)、應用的特定資訊(app-specific),
- 可選的鹽值(Salt),其為一個亂數,是為了增加暴力破解的難度,
通過這些輸入引數,KDF將輸出指定長度的密鑰(Key of required length),
2.6 Diffie-Hellman安全性
Trapdoor function
陷門函式(Trapdoor function),是一種進行正向計算很容易,反向計算極其困難的函式,

(如上圖所示)現在,我們繼續討論Diffie-Hellman密鑰交換問題,在Diffie-Hellman示例中,由于p、g、A、B都是眾所周知的,這意味著黑客Harry也可以訪問這些數字,我們可能會產生疑問:根據p、g、A、B和給定函式能否計算出a、b和S?這種密鑰交換機制安全嗎?
答案是安全的,因為這些用于計算的函式均是陷門函式,例如,如果我們為p、g、a、b選擇好一個值,例如選擇p作為2048位素數,選擇g作為p的模,并選擇a、b為256位隨機整數,在這種情況下,給定p、g和a很容易計算出A,但是給定p、g和A,要計算出a很難,很容易看書,A可以用O(log(a)) 時間復雜度快速計算,這是一個模塊化求冪問題,另一方面,計算a是一個離散對數問題,計算起來要困難得多,這需要我們當前的計算機花費很長的時間解決,所以我們目前的使用Diffie-Hellman至少是安全的,或者直到下一代強大的量子計算機出現后才會受到影響,
雖然Diffie-Hellman是一個需要很長時間解決的問題,但是并不意味著無法解決,是嗎?
如果我們在會話程序中使用的都是固定的密鑰S,又名靜態密鑰(Static Key),將會產生潛在的危險,具體分析如下,
Static Key

(如上圖所示)如果Alice和Bob在他們交流的每個環節中,都使用固定的私鑰a和b,然后發生的是,Harry可以記錄所有這些會話,然后從Session1開始解決a問題,盡管他要花很長時間才能解決,假設在SessionN之后,他得到了正確的a,然后他可以用a來計算出密鑰S,從而他將能解密出所有記錄的會話內容,
以上情況看起來很嚇人!我們要如何預防呢?
答案是使用臨時密鑰(Ephemeral Key),
Ephemeral Key

(如上圖所示)顧名思義,我們在每個會話中使用不同的密鑰(S1、S2…),即使Harry可以解決一次會話的密鑰,他也不能將該密鑰用于其他會話,這在TLS中稱為完全前向保密(Perfect Froward Secrecy),
目前為止,我相信你已經完全了解了Deffie-Hellman Ephemeral DHE的含義,即使用臨時密鑰的Deffie-Hellman密鑰建立協議,
三、非對稱加密(Asymmetric cryptography)
非對稱加密可用于以下三個方面:
- 密鑰交換,例如上文示例中產生的密鑰S
- 加密系統,使用的非對稱加密演算法例如:RSA-OAEP,RSA-PKCS1-v2.2
- 數字簽名,這是非對稱加密的一個重要特征,在TLS中廣泛用于身份驗證,TLS中常用的一些數字簽名演算法是:帶有概率的RSA簽名演算法、Elliptic-Curve數字簽名演算法、Edwards-Curve數字簽名演算法,
在學習數字簽名演算法之前,先來學習下非對稱加密系統是如何作業的?
3.1 作業原理
在非對稱加密體系中:公鑰和私鑰是成對出現的,若是公鑰加密,則私鑰解密,若是私鑰加密,則公鑰解密,即互相解密,在私鑰加密的情形中,又常稱為私鑰簽名,公鑰驗證,即使用場景為:
- 公鑰加密,私鑰解密,公鑰對資訊加密后只有對應的私鑰可以解密,
- 私鑰簽名,公鑰驗證,私鑰對資訊的簽名,指的是私鑰對資訊加密后產生的密文,該密文只有對應的公鑰可以解密,即公鑰擁有者可以驗證該密文是否是私鑰擁有者發出的,

(如上圖所示)同對稱加密一樣,Alice想發送一條訊息給Bob,但是這一次,沒有共享密鑰,而是使用非對稱加密的公私鑰,Alice使用Bob的公鑰(Bob’s public key)對訊息加密,并將加密的訊息發送給Bob,當Bob收到訊息時,它使用自己的私鑰(Bob’s private key)對其進行解密,盡管公鑰和私鑰不同,但是它們仍然可以通過一些陷門函式關聯在一起,就像我們在Diffie-Hellman演算法中看到的一樣,
在非對稱加密的情況下,即使黑客Harry可以訪問Alice的加密訊息和Bob的公鑰,他也不能使用Bob的公鑰來解密訊息,
3.2 如何分享公鑰
由非對稱加密原理可知,分享公鑰變得極其簡單,Bob可以直接通過互聯網將密鑰發送給Alice,無用擔心公鑰可用于解密任何訊息,公鑰分享的關鍵是完全公開的,因此,任何人都可以使用它來加密只有Bob可以閱讀的訊息,其分享流程如下圖所示,

你認為這個公鑰分享方案真的安全嗎?
若直接使用以上公鑰分享方案,其現實情況并不那么簡單,

(如上圖所示)盡管我們知道Harry不能使用Bob的公鑰解密郵件,但他仍然可以干擾公鑰的分享,并用他自己的公鑰替換Bob的公鑰,現在,當Alice收到公鑰時,她仍然認為這是Bob的公鑰,但實際上是Harry的公鑰,因此,如果Alice使用此公鑰加密她的訊息,Harry可以用他的私鑰解密訊息,然后再用Bob的公鑰對解密后的訊息加密,再發送給Bob,如此一來,Bob和Alice在通信程序中對Harry無感知,發生這種情況的原因是,因為公鑰只是一串數字,而沒有身份資訊可以告訴我們其所有者是誰,
那么我們應該如何解決沒有身份資訊的問題呢?
顯然,我們應該將密鑰與一些身份訊息放在一起,然后再共享出去,即所謂的數字證書,于是,Bob把他的公鑰放在證書里,證書上有他的姓名和其他身份資訊,該證書就像現實世界中的護照一樣,
但是我們如何知道真正擁有證書的是Bob?是如何阻止了Harry用Bob的名字,但用Harry的公鑰制作假證書?

(如上圖所示)就像現實世界中一樣,護照必須由護照頒發機構經過身份驗證的程序后簽發,在數字世界中,證書必須由證書頒發機構驗證并簽名,該證書頒發機構和護照頒發機構均是受信任的第三方,
3.3 數字證書的獲取
獲取數字證書,即證書頒發機構對數字證書的頒發程序,

(如上圖所示)Bob已有一對公鑰和私鑰,現在他準備開始申請證書頒發機構對數字證書的簽名:
- 創建證書簽名請求CSR(Certificate Signing Request),該CSR包含他的公鑰和一些身份資訊,例如他的姓名、組織或電子郵件,
- 使用Bob的私鑰對CSR進行簽名(就像我們在護照上簽名一樣),然后將已簽好名的CSR發送給證書頒發機構(Certificate Authority,簡稱CA),
- CA用證書中Bob的公鑰來驗證他的簽名,這是為了確保Bob確實擁有CSR中公鑰所對應的私鑰,如有必要,還需聯系Bob驗證其身份,
- CA使用自己的私鑰在證書上簽名(就像護照頒發機構在護照上蓋一個鋼印,然后將其發送回Bob,
現在,Bob與Alice可以共享此證書,證書中包含Bob的公鑰和一些身份資訊,而不是像以前那樣僅發送公鑰,Alice收到證書后,Alice可以使用證書頒發機構的公鑰輕松驗證證書的真實性,因此,Harry無法再用他的公鑰替換Bob的公鑰,因為他沒有CA的私鑰來簽名假證書,數字證書的共享流程如下圖所示:
請注意,以上的安全的前提是我們都信任CA,如果以某種方式CA不可信,例如,如果CA給Harry他們的私鑰,那么我們將面臨嚴重的危險!解決CA可信問題的方法是,使用CA鏈,
3.4 CA鏈
CA鏈是為了解決CA的可信任問題,

(如上圖所示)CA鏈的頂層是根證書頒發機構(Root Certificate Authority),它可以簽署自身證書與簽署中間CA(Intermediate Certificate Authority)證書,而該中間CA又可以簽署其子節點CA證書,或者他們可以直接簽署最終物體證書(即葉子證書),如此,確保每個證書都參考了其上一節點的證書,可以追溯到根節點的證書,例如我們使用葉子節點的公鑰解密(驗證)葉子節點證書簽名后,可以獲得上一節點的簽名,直至根節點,
在我們使用的作業系統和瀏覽器中存盤了受信任的根證書頒發機構的證書串列,這樣,作業系統和瀏覽器就可以輕松地驗證所有證書的真實性,
3.5 數字證書的簽名與驗證

(如上圖所示)數字證書的簽名與驗證流程:
CA對證書的簽名:
- Hash:CA使用Hash演算法計算出簽署內容的一個Hash值,即d95e0dba36,
- Encrypt:CA使用其私鑰對Hash值進行簽名,簽名值為1f96d4c362,
- Attach:簽名附加到證書檔案中,就完成了對證書的數字簽名,
用戶驗證證書:
- Detach:從已簽名證書中決議出簽名(1f96d4c362)與不帶簽名的證書,
- Decrypt:使用CA的公鑰對簽名進行解密,獲取到加密前的Hash值(d95e0dba36),
- Hash:對不帶簽名的證書進行哈希運算,獲取到Hash值,例如為:d95e0dba36,
- Compare:對比前后兩個Hash值,如果它們相同,則簽名有效,
至此,我們已經了解了對稱加密與非對稱加密,下面將探索如何在TLS 的握手協議中使用這兩種加密方式,
四、TLS 1.3 握手流程
4.1 完整的握手流程

TLS 1.3 完整的握手流程主要包括以下三個步驟,
1、首先是客戶端到服務器的Client Hello,訊息內容包括:
- 支持的協議版本:TLS 1.3 或 TLS 1.2,
- 支持的對稱密鑰套件:TLS_AES_256_GCM_SHA384 或 TLS_CHACHA20_POLY1305_SHA256,
- 支持的密鑰協定(交換)演算法:DHE(Diffie-Hellman Ephemeral) 或 ECDHE(Elliptic-Curve Diffie-Hellman Ephemeral),
- 分享的密鑰:客戶端的DHE公鑰,客戶端的ECDHE公鑰,用于計算臨時的共享密鑰,即前文示例中的S,
- 支持的簽名演算法:RSA-PSS 或 ECDSA,由服務器選擇使用哪種演算法對整個握手進行簽名,
2、 收到客戶端的Client Hello后,服務器將回復一個Server Hello,訊息內容包括:
- 選擇的協議版本:TLS 1.3.
- 選擇的對稱密鑰套件:TLS_AES_256_GCM_SHA384,
- 選擇的密鑰協定演算法:DHE,
- 分享的密鑰:服務器的DHE公鑰,
- 證書請求:對客戶端證書的請求,可選值,通常在HTTPS中,只需要服務器將其證書發送給客戶端即可,,
- 服務器證書:服務器的證書,
- 證書驗證:對整個握手訊息的簽名,生成方式:從客戶端的握手開始,直到證書請求為止,都稱為握手背景關系(Handshake context),然后將握手的背景關系以及服務器的證書經過Hash運算,得到一個hash值,例如4ab31d2,然后使用服務器的私鑰對hash值進行簽名,使用的簽名演算法為客戶端支持的演算法之一,最后獲得填寫的簽名值,
- 服務完成:為一個MAC值(訊息認證碼),生成方式:對握手上背景關系+服務器證書+證書驗證進行Hash運算,再將hash值通過所選的密碼套件計算出MAC值,
3、客戶端收到Server Hello后,將通過根CA驗證服務器證書,然后檢查簽名和MAC值,確保訊息沒有被篡改,若一切順利,則客戶端將發送一個握手結束訊息,結束訊息中包括:
- 由握手背景關系計算的MAC值、以及可選的客戶端證書和證書驗證,
以上便是TLS 1.3中的完整握手流程,
4.2 預共享密鑰
預共享密鑰(Pre-Shared Key),簡稱PSK,

(如上圖所示)為了提高效率,客戶端與服務器并不會每次都經過完整的握手流程,有時他們僅執行簡短的握手流程,實作方法是通過預共享密鑰恢復狀態:經過前一次握手,客戶端與服務器已經相互了解,因此他們不需要再次進行身份驗證,因此,服務器可以向客戶端發送一個或多個會話憑證(session ticket),可以在下一次握手中用預共享密鑰(PSK)、憑證過期時間以及其他一些資訊用作身份驗證,
在使用PSK的簡短握手流程中,客戶端將發送一條簡單的問候訊息,其中包括上一次握手獲得的PSK身份標識(憑證)和PSK密鑰交換模式,如果使用具有Diffie-Hellman模式的PSK,客戶端還需要共享其Diffie-Hellman公鑰,如有需要,允許服務器回退到完整的握手流程,服務器收到此客戶端的問候訊息時,它將回傳帶有選定的預共享密鑰標識訊息,服務器可在回傳訊息中帶有可選的Diffie-Hellman公鑰,最后,客戶端發送給服務器一個完成訊息,
可以看出,在該簡短的握手流程中,客戶端與服務器之間沒有證書身份驗證,這為零個往返時間(0-RTT)提供了機會,
4.3 0-RTT
0-RTT(Zero Round-Trip Time)意味著,客戶端無需等待握手完成,就可將第一個應用請求資料發送給服務器,

(如上圖所示)在0-RTT中,客戶端將應用程式資料(Application data)和客戶端Client Hello訊息一起發送,客戶端使用Pre-shared key欄位中的第一個PSK派生的密鑰對資料進行加密,同時,該Client Hello增加了早期資料指示(Early data indication)欄位,告訴服務器有早期的應用資料正在發送,如果服務器接收此0-RTT請求,它會像正常的PSK恢復一樣發送一個回復訊息,可能回復訊息中帶有一些可選的應用程式資料,最后,客戶端發送一個帶有早期資料的結束與MAC值得結束訊息,
以上就是TLS 1.3中0-RTT的作業方式,它的優點時將延遲減少了 1 個往返時間,但是,其缺點是將會收到重放攻擊的潛在威脅,意思是,黑客可以復制并發送相同加密的0-RTT請求多次訪問服務器,為了避免這種情況,必須實作服務器應用程式對重復請求的方式限制,例如1s之內只能訪問5次,
希望你也有所識訓!
參考文獻:A complete overview of SSL/TLS and its cryptographic system
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/253150.html
標籤:區塊鏈
上一篇:為什么新手玩合約總是爆倉?
