術語掃盲

80埠:80埠是為HTTP(HyperText Transport Protocol)即超文本傳輸協議開放的默認埠

443埠:443埠即網頁瀏覽埠,主要是用於HTTPS服務,是提供加密和通過安全埠傳輸的另一種HTTP。是https的默認埠。

小結:訪問網頁如不加埠號,使用http協議訪問網頁,是請求的伺服器的80埠;使用https協議請求的是伺服器的443埠。


SSL(Secure Sockets Layer 安全套接層):位於可靠的面向連接的網路層協議和應用層協議之間的一種協議層。SSL通過互相認證、使用數字簽名確保完整性、使用加密確保私密性,以實現客戶端和伺服器之間的安全通訊。該協議由兩層組成:SSL記錄協議和SSL握手協議。

TLS:(Transport LayerSecurity,傳輸層安全協議):用於兩個應用程序之間提供保密性和數據完整性。該協議由兩層組成:TLS記錄協議和TLS握手協議。

TLS記錄協議:是一種分層協議,,這種協議被用來封裝幾種高層協議(如HTTP,SMTP等)。使用有TLS握手協議產生的安全參數,它首先將上層被傳輸的數據分片成便於管理的塊,然後對數據有選擇性地壓縮,計算出消息認證碼MAC(如MD5或SHA),加密(如NULL,DES,3DES等),最後將結果送出。接收到的數據經過解密,校驗,解壓縮,重組後被傳輸到上層客戶端。TLS記錄協議位於TLS握手協議的下面,在可靠的傳輸協議(如TCP/IP)上面。其負責識別不同的消息類型,以及每條消息的完整性、安全性驗證。

小結:兩個協議都是一種安全協議,目的是為互聯網通信提供安全及數據完整性保障。SSL協議的發展歷史比較早,第一版由於漏洞比較多,1994年公布了第二個版本。1996年5月, TLS工作組成立,開始將SSL從Netscape遷移至IETF。SSL是Netscape開發的專門用戶保護Web通訊的,目前版本為3.0。最新版本的TLS 1.0是IETF(工程任務組)制定的一種新的協議,它建立在SSL 3.0協議規範之上,是SSL 3.0的後續版本。兩者差別極小,可以理解為SSL 3.1,它是寫入了RFC的。 SSL 3.0和TLS 1.0有輕微差別,但兩種規範其實大致相同。

網景公司(Netscape)在1994年推出首版網頁瀏覽器,網景導航者時,推出HTTPS協議,以SSL進行加密,這是SSL的起源。IETF將SSL進行標準化,1999年公布第一版TLS標準文件。隨後又公布RFC 5246 (2008年8月)與 RFC 6176 (2011年3月)。在瀏覽器、電子郵件、即時通信、VoIP、網路傳真等應用程序中,廣泛支持這個協議。


X.509: 是密碼學裡公鑰證書的格式標準。 X.509 證書己應用在包括TLS/SSL在內的眾多 Intenet協議里.同時它也用在很多非在線應用場景里,比如電子簽名服務。X.509證書里含有公鑰、身份信息(比如網路主機名,組織的名稱或個體名稱等)和簽名信息(可以是證書籤發機構CA的簽名,也可以是自簽名)。對於一份經由可信的證書籤發機構簽名或者可以通過其它方式驗證的證書,證書的擁有者就可以用證書及相應的私鑰來創建安全的通信,對文檔進行數字簽名.

OpenSSL:OpenSSL是一個開源項目,包括密碼庫和SSL/TLS工具集。 OpenSSL項目是安全套接字層(secure sockets layer, SSL)和傳輸層安全(transport layer security, TLS)協議的一個實現,是大家共同努力開發出的代碼可靠、功能齊全、商業級別的開源工具集。 可以使用該項目生成數字證書。

HTTPS:超文本傳輸安全協議(英語:Hypertext Transfer Protocol Secure,縮寫:HTTPS,常稱為HTTP over TLS、HTTP over SSL或HTTP Secure)是一種通過計算機網路進行安全通信的傳輸協議。HTTPS經由HTTP進行通信,但利用SSL/TLS來加密數據包。HTTPS開發的主要目的,是提供對網站伺服器的身份認證,保護交換數據的隱私與完整性。它其實就是HTTP+加密+身份認證+完整性保護

OSI模型層

開放系統互聯(open systems interconnection, OSI):網路通信的理論模型,簡單來說,所有的功能都被映射到七個層上。最底層是最接近物理通信鏈路的層,後面的層依次建立在其他層之上,提供更高級別的抽象。最頂層就是應用層,攜帶著應用數據

現實中的協議並非總能與OSI模型完全對應。比如SPDY和HTTP/2因為要對連接進行管理,所以被歸入會話層協議,但它們卻在數據加密以後生效。第五層及更高層的劃分經常是模糊的。

OSI參考模型 和 TCP/IP協議群

證書

內容欄位

一般遵從X.509格式規範的證書,會有以下的內容,它們以欄位的方式表示:

  • 版本:現行通用版本是 V3
  • 序號:用以識別每一張證書,特別在撤消證書的時候有用
  • 主體:擁有此證書的法人或自然人身份或機器,包括:
  • 國家(C,Country)
  • 州/省(S,State)
  • 地域/城市(L,Location)
  • 組織/單位(O,Organization)
  • 通用名稱(CN,Common Name):在TLS應用上,此欄位一般是網域
  • 發行者:以數字簽名形式簽署此證書的數字證書認證機構
  • 有效期開始時間:此證書的有效開始時間,在此前該證書並未生效
  • 有效期結束時間:此證書的有效結束時間,在此後該證書作廢
  • 公開密鑰用途:指定證書上公鑰的用途,例如數字簽名、伺服器驗證、客戶端驗證等
  • 公開密鑰
  • 公開密鑰指紋
  • 數字簽名
  • 數字簽名演算法
  • 主體別名:例如一個網站可能會有多個網域(www.wikipedia.org, zh.wikipedia.org, zh.m.wikipedia.org 都是維基百科)、一個組織可能會有多個網站(.wikipedia.org, .wikibooks.org, *.wikidata.org 都是維基媒體基金會旗下的網域),不同的網域可以一併使用同一張證書,方便實現應用及管理

申領及使用

向證書機構申領簽發電子證書的進程

數字證書一般由數字證書認證機構簽發,簡單的程序如下:

申領

  1. 鮑伯在自己的機器上使用密碼學安全偽隨機數生成器產生一對足夠強的密鑰
  2. 鮑伯的私鑰不會向任何人發送
  3. 鮑伯把他的公鑰,連同主體消息、使用目的等組成證書籤署請求,發送給發行人伊凡
  4. 伊凡(用另外一些渠道)核實鮑伯的身份
  5. 如果伊凡信任這個請求,他便使用鮑伯的公鑰和主體消息,加上證書有效期、用途等限制條件,組成證書的基本數據
  6. 伊凡用自己私鑰在證書上加密簽署
  7. 伊凡把加密好的證書發送給鮑伯(伊凡也可以透過證書透明度公布他簽發了新的證書)

使用

主條目:公開密鑰加密 § 加密過程

  1. 鮑伯與愛麗絲事先可能互不認識,但鮑伯與愛麗絲都信任伊凡,愛麗絲驗證過證書上伊凡的簽署有效無誤後,便可以信任證書是屬於鮑伯的
  2. 愛麗絲可以使用證書上的公鑰加密明文,得到密文並發送給鮑伯
  3. 鮑伯可以可以用自己的私鑰把密文解密,得到明文

單元格式

電子證書可以二進位或Base64形式存儲,常見的二進位文件擴展名有 .cer、.crt、.der,Base64的文件擴展名則通常是 .pem。如果把證書和私鑰一起存儲,則可以使用PKCS#12(.p12)格式。

HTTPS工作原理

HTTPS是利用SSL/TLS來加密數據包的。本結通過TLS 1.2 的宏觀概述,來理解HTTPS的工作原理。

TLS協議由兩層組成:TLS記錄協議和TLS握手協議。

TLS握手協議

每一個TLS連接都會以握手開始。 儘管可以選擇對任意一端進行身份驗證,但人們幾乎都啟用了對伺服器的身份驗證。完整的握手如圖所示

1. Client Hello

  • 客戶端發起TLS握手請求

struct {
ProtocolVersion client_version;
Random random;
SessionID session_id;
CipherSuite cipher_suites<2..2^16-2>;
CompressionMethod compression_methods<1..2^8-1>;
select (extensions_present) {
case false:
struct {};
case true:
Extension extensions<0..2^16-1>;
};
} ClientHello;

  • 數據包括內容:

  • ProtocolVersion/協議版本(客戶端期望支持的握手協議版本)
  • Random/安全隨機數(MasterSecret生成用到,協議文檔裡面說是28個位元組,但是實際抓包看到是32個位元組,這裡懷疑是各個協議文檔版本不同,還有使用加密套件的不同,導致的差異,具體博主就沒有在繼續深究了,如果有朋友知道可以留言給我)
  • SessionID/會話ID
    • 這個值是被服務端設置的,如果這個值為空,表示客戶端與服務端沒有存活的https會話,需要與服務端進行完整的握手。
    • 如果這個值存在,則表明客戶端期望恢復上一次的https會話,這時候客戶端與服務端只需要進行快速的握手過程。(這裡我們只會分析完整的握手過程進行學習)

  • CipherSuite/加密套件(客戶端支持的加密套件列表)
    • 如果sessionid不為空,可以不傳這個值,服務端可以從上一次會話中恢復這個值。
    • 每個加密組件(Cipher Suite)都包括了下面5類演算法

TLS Cipher Suite Registry

,圖中百度使用的是就是 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

這個加密套件:

    • 1、authentication (認證演算法):RSA
    • 2、encryption (加密演算法 ):AEAD_AES_128_GCM
    • 3、message authentication code (消息認證碼演算法 簡稱MAC):SHA256
    • 4、key exchange (密鑰交換演算法):ECDHE
    • 5、key derivation function (密鑰衍生演算法)

  • CompressionMethod/壓縮方法
    • 加密前進行數據壓縮
    • 因為壓縮方法被攻擊,在TLS1.3協議版本上已經徹底禁止壓縮了。(這裡有兩種攻擊方式BREACH、CRIME,有時間博主會來研究)
  • Extension/擴展數據(session ticket在擴展裡面,可見下圖)
  • 消息內容如下圖:

2. Server Hello

  • 服務端回應Client Hello請求

struct {
ProtocolVersion server_version;
Random random;
SessionID session_id;
CipherSuite cipher_suite;
CompressionMethod compression_method;
select (extensions_present) {
case false:
struct {};
case true:
Extension extensions<0..2^16-1>;
};
} ServerHello;

  • 主要發送數據內容:
  • ProtocolVersion/握手協議版本

    • 服務端最高支持的握手協議版本,TLS/SSL協議都是向下兼容的。

  • Random/隨機數
    • 服務端生成32位元組安全隨機數(MasterSecret生成會用到)
  • SessionID/會話ID
    • 如果客戶端hello有發送session id,服務端從內存中查找,並嘗試恢復之前的會話狀態。
    • 恢復成功,服務端返回同樣的session id。
    • 恢復不成功,服務端此欄位返回空。

  • CipherSuite/加密組件
    • 服務端從客戶端hello的cipher suite列表中選擇一個加密套件,如果是恢復上一次的會話,則從會話狀態中恢復上一次相同的加密套件。
  • CompressionMethod/壓縮方法
    • 服務端從客戶端hello的compression_methods列表中選擇一個壓縮方法,如果是恢復上一次的會話,則從會話狀態中恢復上一次相同的壓縮方法。

  • Extension/擴展(如下圖)
  • 消息如下面所示:

3. Server Certificate

  • 服務端發送的是一個證書鏈,可能包含多個證書
  • 第一個證書為網站的證書。
  • 第二個證書為頒發證書給網站的機構的證書。
  • 在這個例子中第三個證書是CA機構的根證書,可以忽略不用發送,因為這個CA的根證書是CA自己給自己頒發的。 這裡構成了一個證書信任鏈,也就是 GlobalSign Root CA信任GlobalSign Organization Validation CA,而他又信任baidu.com的證書。 如下圖所示:

  • CA證書的類型有3類:DV ( domain validation),OV ( organization validation),EV ( extended validation),證書申請難度從前往後遞增。
  • 證書中都包含了哪些信息? ```html
  • 證書版本號(Version)
  • 證書序列號(Serial Number)
  • 簽名演算法標識符(Signature Algorithm) 簽名演算法標識用來指定由CA簽發證書時所使用的"簽名演算法"。演算法標識符用來指定CA簽發證書時所使用的: 1) 公開密鑰演算法 2) hash演算法 example: sha256WithRSAEncryption 須向國際知名標準組織(如ISO)註冊
  • 簽發機構名(Issuer)
  • 有效期(Validity):指定證書的有效期
  • 證書用戶名(Subject)
  • 證書持有者公開密鑰信息(Subject Public Key Info) 證書持有者公開密鑰信息域包含兩個重要信息: 1) 證書持有者的公開密鑰的值 2) 公開密鑰使用的演算法標識符。此標識符包含公開密鑰演算法和hash演算法。
  • 擴展項(extension)
  • 簽發者唯一標識符(Issuer Unique Identifier)
  • 證書持有者唯一標識符(Subject Unique Identifier)
  • 簽名演算法(Signature Algorithm)
  • 簽名值(Issuers Signature) ```
  • 如下圖所示

如何校驗服務端證書呢?

  • 簽名的生成:CA先將證書信息生成hash摘要,然後再用CA機構的私鑰進行加密。
  • 簽名的校驗:使用CA機構的公鑰進行解密簽名,得到hash摘要A,再計算證書信息的hash摘要B。比對是否一致。 #### 詳細解釋服務端的證書是怎麼生成的?
  • 服務端的證書是由CA (Certificate Authority,證書認證中心)頒發的。他是一個負責發放和管理數字證書的第三方權威機構,它負責管理PKI(Public Key Infrastructure,公開密鑰基礎設施)結構下的所有用戶(包括各種應用程序)的證書,把用戶的公鑰和用戶的其他信息捆綁在一起,在網上驗證用戶的身份。
  • 一般情況下網站方向CA申請一個證書。CA會給網站方生成一對非對稱加密的公鑰私鑰,公鑰會做到證書裡面,私鑰則會給到網站方。
  • CA會先做一個「數字簽名」(生成過程:明文 --> hash運算 --> 摘要 --> 私鑰加密 --> 數字簽名)
  • 就是將網站方的信息網站方的公鑰簽名演算法等信息(就是Wireshark Packet 20中的數據,除了「簽名值」),計算一個hash值(圖中hash演算法是SHA256),然後CA再用自己私鑰做加密(圖中公開密鑰演算法是RSA),最後的這個密文就是「數字簽名」(也就是我們在圖中看到「encrypted」簽名值)。
  • CA最後將「網站方信息」、「網站方公鑰」、「簽名演算法」、「簽名值」都做到證書裡面(就是Wireshark Packet 20中的我們看到那些數據),證書就做好了,CA會把「證書」和「網站方的私鑰」給到網站方。

CA怎麼驗證證書是不是自己頒發的呢?以及做證書內容校驗?

  • 首先瀏覽器(校驗網站的證書)或操作系統(校驗應用的證書),會在操作系統存儲的系統信任的根證書裡面去查找「證書頒發機構」是否是信任的。如下圖系統根證書:

* 瀏覽器通常也會內置大多數主流權威CA的根證書。
* 如果查找不到對應的可信CA,則判斷這個證書是偽造的,不可信的。(瀏覽器則會提醒該證書不是可信任機構頒發的,並詢問是否要繼續訪問)

  • 如果找到對應的CA機構,則取出CA機構證書裡面的公鑰信息,將網站方證書中的簽名值(也就是數字簽名)做解密,得到網站證書信息的hash摘要A。
  • 然後將網站證書中的信息,做hash得到摘要B,比對摘要A和摘要B是否一致。如果不一致,說明網站證書中的信息被修改了。(瀏覽器則會提醒該證書不是可信任機構頒發的,並詢問是否要繼續訪問)
  • 如果摘要hash一致,則說明證書中的信息未被修改,這時瀏覽器會比對您現在正在訪問的網站與證書中網站信息是否一致,比如域名是否一致、證書是否在有效期內等。(如果出現問題,瀏覽器將會提醒你,並詢問是否要繼續訪問)
  • 另外大部分瀏覽器也會在線校驗證書,是否在有效期內(將證書序列號通過在線證書狀態協議「OCSP」發送給CA做校驗)。
  • 證書校驗成功,最後將從證書中取出網站方的公鑰,用於後面的握手簽名。

4. Server Key Exchange

  • 這個步驟是密鑰協商的服務端部分,最終的密鑰將會用於傳輸數據對稱加密。
  • 服務端需要發送一個Diffie-Hellman演算法的公鑰,和指定使用哪種橢圓曲線多項式。
  • 我們到Client Key Exchange的時候,再來講這個密鑰協商過程。
  • 這裡還有一個簽名,校驗這個流程的數據是否被篡改。如下圖所示,客戶端收到Server Key Exchange數據後,可以用上個流程中獲得的證書公鑰對簽名值解密,獲得摘要A。並將這次數據明文做SHA512的hash,獲得摘要B,做比對。(這裡對協商演算法做簽名校驗,目的可能是防止中間人對協商演算法方式做篡改,雖然DH演算法不擔心公鑰在不安全的網路中傳輸,但是其他演算法可能需要考慮被篡改的情況。所以猜測服務端密鑰協商時做簽名是這個目的,因為服務端這時已經確定是DH演算法了,所以客戶端協商時就不需要做簽名了,DH演算法不需要考慮這個安全問題)
  • 發送的數據如下圖示:

5. Server Hello Done

  • 服務端發送ServerHelloDone消息表示,已經發送完了密鑰協商需要的消息,並且客戶端可以開始進行客戶端的密鑰協商處理了,也就是Client Key Exchange。
  • 收到ServerHelloDone後,客戶端需要確認伺服器是否提供了合法的證書,並且確認伺服器的ServerHello消息裡面的參數是否可以接受。

6. Client Key Exchange

  • 客戶端生成自己用於密鑰協商的公私鑰,並發送此公鑰
  • 這時客戶端已經知道了服務端密鑰協商的公鑰以及自己的公鑰
  • 我們以EC Diffie-Hellman密鑰協商協議為例,來看看客戶端、服務端是怎麼協商出相同的密鑰的(這裡協商出來的是PreMasterSecret,不是最終的對稱加密用到的密鑰)。
  • EC Diffie-Hellman使用到一個數學難題,就是在給定的橢圓曲線上的一個點P,一個整數k,求Q=kP很容易;但是給定一個點P、Q,知道Q=kP,求整數k確實很難。
  • 服務端確定了密鑰協商演算法為「EC Diffie-Hellman」,發送給客戶端。現在兩端都知道了使用的是哪個曲線參數(橢圓曲線E、階N、基點G)。
  • Server Key Change:服務端隨機生成一個整數a,計算A=a*G,生成服務端公鑰A,發送給客戶端。
  • Client Key Change:客戶端隨機生成一個整數b,計算B=b*G,生成服務端公鑰B,發送給服務端。
  • 客戶端計算出PreMasterSecret:Q=bA=b(a*G)
  • 服務端計算出PreMasterSecret:Q=aB=a(b*G),這兩個計算結果是相等的,此時雙方協商好對稱密鑰值。
  • 並且即使攻擊者截獲到雙方公鑰A、B,仍然無法計算出PreMasterSecret,因為攻擊者需要知道隨機整數a、b的其中任意一個,可是之前我們就提到過EC Diffie-Hellman協議中,知道A、G求a是很難的。
  • 真正對稱加密使用到的密鑰生成(這裡使用到了client、server一開始hello中傳輸的隨機數):
  • MasterSecret = PRF(PreMasterSecret, "master secret", Client.random || Server.random)[0..47] -- 固定取前 48 位元組
  • KeyBlock = PRF(MasterSecret, "key expansion", Server.random || Client.random) -- 長度為由雙方確定的密碼演算法套件決定
  • KeyBlock才是最終用來做對稱加密的密鑰塊 6.3. Key Calculation

7. Client Change Cipher Spec

  • 這個過程就是告訴服務端,他已經準備好MasterSecret了,可以進行數據加密傳輸了。
  • 這個協議是冗餘的,在TLS 1.3裡面直接被刪除了。

8. Client Finished

  • 這條消息是用來確定雙方的MasterSecret是否正確生成,發送的是verify_data消息。

struct {
opaque verify_data[verify_data_length];
} Finished;

verify_data
PRF(master_secret, finished_label,Hash(handshake_messages))
[0..verify_data_length-1];

  • verify_data = PRF(master_secret, finished_label, Hash(handshake_messages))
  • PRF是偽隨機函數(pseudorandom function,PRF)
  • master_secret是密鑰協商時,計算出來的
  • finished_label:對客戶端發的Finished消息來說,固定是字元串 "client finished". 對伺服器發的Finished消息來說,固定是字元串 "server finished".

struct {
HandshakeType msg_type; /* handshake type */
uint24 length; /* bytes in message */
select (HandshakeType) {
case hello_request: HelloRequest; //HelloRequest是服務端在任何時候都可以發出的,告訴客戶端需要重新進行握手協議,客戶端隨即發送新的ClientHello
case client_hello: ClientHello;
case server_hello: ServerHello;
case certificate: Certificate;//服務端或客戶端發送自己證書給客戶端。
case server_key_exchange: ServerKeyExchange;
case certificate_request: CertificateRequest;//服務端請求,客戶端發送自己的客戶端證書,給服務端做校驗。這個步驟在博文中沒有提到,看以後有需要再了解。
case server_hello_done: ServerHelloDone;
case certificate_verify: CertificateVerify;//客戶端發出,從client hello開始,一直到CertificateVerify之前的所有消息的hash加上客戶端證書對應私鑰的加密結果。
case client_key_exchange: ClientKeyExchange;
case finished: Finished;
} body;
} Handshake;

  • 但不包括ChangeCipherSpec、alerts之類的消息。並且最後一個發送Finished的一方,需要把前一個發送Finished的內容包括進去。
  • 注意這裡每個端發送自己的握手消息就可以,比如Client發送內容包括ClientHello、Certificate(有發送的話)、CertificateVerify(如果有發送的話)、ClientKeyExchange、Finished(如果是最後一方需要包含)。服務端同理。

  • 因為verify_data是加密的,我就沒有在截圖了,上述的欄位以及說明可以查看協議文檔 7.4.9. Finished

8.1. Server New Session Ticket

  • 如果服務端想使用Ticket方式存儲session狀態,在Server Change Cipher Spec之前就需要發送New Session Ticket消息。
  • New Session Ticket方式與Session ID方式對比:
  • SessionID方式,客戶端在ClientHello的時候帶著上一次SessionID過來,服務端從自己內存中查找SessionID對應的session狀態,並讀取session狀態快速恢復。

struct {
ProtocolVersion protocol_version; //協議版本
CipherSuite cipher_suite; //加密套件類型
CompressionMethod compression_method; //壓縮方法
opaque master_secret[48]; //對稱密鑰
ClientIdentity client_identity; //客戶端ID
uint32 timestamp;//ticket有效期
} StatePlaintext;

9. Server Change Cipher Spec

  • 告訴客戶端,我已經準備好進行加密傳輸了。

10. Server Finished

  • 與8. Client Finished的情況一樣,使用對稱密鑰加密,最後做一次驗證,確定雙方是否都準備好進行數據傳輸了。只是這裡加密的數據還不是真正的網站內容數據,而是握手過程的數據。

11. Application Data

  • 真正的網站數據傳輸,但是這裡的數據就是經過握手時協商好的對稱密鑰進行加密的了。
  • 現在我們有KeyBlock(對稱密鑰塊),也知道對稱加密演算法是AES-128-GCM 5.1. AEAD_AES_128_GCM

偽隨機數函數:

PRF 是一個「偽隨機數函數」,這個函數很聰明,在規約中也有定義。它使用基於哈希的消息驗證碼(HMAC)的MD5SHA-1兩種哈希函數將密鑰,ASCII 字元以及我們給的種子結合起來。對每個哈希函數發送一半的輸入。說它聰明的原因是即使面對MD5和 SHA-1 的弱點,它的防攻擊能力還很強。這個過程可以自我反饋並不停地循環,而且我們要多少位元組就能生成多少。

依照這個過程,我們獲得以下 48 位元組的「master secret」:

4C AF 20 30 8F 4C AA C5 66 4A 02 90 F2 AC 10 00 39 DB 1D E0 1F CB E0 E0 9D D7 E6 BE 62 A4 6C 18 06 AD 79 21 DB 82 1D 53 84 DB 35 A7 1F C1 01 19

多個密鑰的生成

現在雙方都有了「master secrets」,規約描述了我們如何生成會話所需的所有的密鑰,我們需要使用 PRF 函數來創建一個「key block」,然後從這個塊中提取所需的密鑰:

key_block = PRF(SecurityParameters.master_secret, "key expansion", SecurityParameters.server_random + SecurityParameters.client_random);

「key_block」被用來提取以下密鑰:

client_write_MAC_secret[SecurityParameters.hash_size]

server_write_MAC_secret[SecurityParameters.hash_size] client_write_key[SecurityParameters.key_material_length] server_write_key[SecurityParameters.key_material_length] client_write_IV[SecurityParameters.IV_size] server_write_IV[SecurityParameters.IV_size]// 密鑰塊的作用1 -- client_write_MAC_secret 客戶端MAC密鑰,生成消息的認證碼,對方用其驗證消息 2 -- server_write_MAC_secret 伺服器MAC密鑰,生成消息的認證碼,對方用其驗證消息 3 -- client_write_key 客戶端加密密鑰,加密客戶端發送的消息,對方用其解密 4 -- server_write_key 伺服器加密密鑰,伺服器加密發送的消息,對方用其解密 5 -- client_write_IV 客戶端IV,與客戶端加密密鑰配合使用(分組密碼演算法) 6 -- server_write_IV 伺服器IV,與伺服器加密密鑰配合使用(分組密碼演算法)

由於這裡使用的是序列密碼而非分組密碼(如高級加密標準AES),所以不需要初始向量(Initialization Vectors IV),而只是雙方各需要一個 16 位元組(128 比特)的消息驗證碼(Message Authentication Code MAC),這是因為指定的 MD5 哈希摘要大小是 16 位元組。另外,RC4 加密演算法使用的 16 位元組的密碼也是雙方都需要的。最後,我們需要 key block 中的 216 + 216 = 64 個位元組:

運行 PRF,我們得到:

client_write_MAC_secret = 80 B8 F6 09 51 74 EA DB 29 28 EF 6F 9A B8 81 B0

server_write_MAC_secret = 67 7C 96 7B 70 C5 BC 62 9D 1D 1F 4A A6 79 81 61 client_write_key = 32 13 2C DD 1B 39 36 40 84 4A DE E5 6C 52 46 72 server_write_key = 58 36 C4 0D 8C 7C 74 DA 6D B7 34 0A 91 B6 8F A7

準備加密!

小結:

上面的實例描述了TLS握手協議的流程,內容比較多。其中有幾處關鍵的加密過程這裡再總結一下。

公鑰和私鑰:加密演算法分為兩種,對稱加密和非對稱加密。

對稱加密是最快速、最簡單的一種加密方式,加密(encryption)與解密(decryption)用的是同樣的密鑰(secret key)。

非對稱加密為數據的加密與解密提供了一個非常安全的方法,它使用了一對密鑰,公鑰(public key)和私鑰(private key)。

使用公鑰和私鑰的加密方式是非對稱加密。公鑰和私鑰的名稱區別是已秘鑰提供者來做區分的。不管伺服器還是客戶端,向申請者提供的密鑰都是公鑰,自己保存的私鑰。也就是說伺服器和客戶端都是可以充當密鑰提供方的角色的,私鑰只能保存在秘鑰提供方的手裡,而公鑰是可以公開的。如果需要和密鑰提供方進行交互,就需要使用對應的密鑰提供發提供的公鑰對數據加密,加密後的數據只有密鑰提供方來使用自己的私鑰來解密。總結來說就是:公鑰加密,私鑰解密;客戶端和伺服器都可能有自己對應的公鑰和私鑰

三個隨機數:握手過程中產生了三個隨機數

第一個隨機數是客戶端發送Client Hello請求時,在客戶端生成,發送給伺服器的。

第二個隨機數是伺服器發送Server Hello請求時,在伺服器生成,發送給客戶端的。

第三個隨機數是客戶端校驗證書通過後,在客戶端生成的。這個隨機數會通過證書裡面的公鑰進行加密,然後再發給伺服器,這個隨機數稱為PreMasterSecret。(這是使用RSA演算法實現的,其他的密鑰交換演算法還有DHE_RSA、ECDHE_RSA和ECDHE_ECDSA 後面的這三種演算法實現起來都RSA複雜,如果不是做這方面的業務或者數學功底比較強的,建議不要去研究)。

三個隨機數用來生成MasterSecret

####

參考文獻

《HTTPS權威指南》

HTTP和TCP的區別

TLS握手協議分析與理解——某HTTPS請求流量包分析

HTTPS 連接最初的若干毫秒

安全協議系列(四)----SSL與TLS

圖解SSL/TLS協議


推薦閱讀:
相关文章