那些關於SSL/TLS的二三事(九) — SSL (HTTPS)Communication

Carl
14 min readMay 22, 2018

--

前一篇文章裡簡單介紹了加密系統的原理及其背後常見的各種演算法, 這篇就要來詳細的看一下 SSL 通訊機制的背後是怎麼實現的了.

首先, 可以從下面這張完整的流程圖開始看起:

SSL Communication Flow Diagram

左邊是 client (browser), 右邊是 server (website). 我們知道, 對於 internet 通訊來說, 都是從 TCP 連線的初始化開始的, 即所謂的 3-way-handshake (SYN, SYN+ACK 以及 ACK), 所以這邊就不畫出來了.

一旦 client 與 server 之間的 TCP 連線建立起來後, SSL handshake就開始了.

上面的順序圖展示了 SSL 通訊過程中的各種步驟. 這些步驟可以被歸類成以下三個階段:

  1. Authentication (Handshake): 使用 Public/Asymmetric Key Encryption Algorithms.
  2. Key Exchange (Handshake): 使用 Public/Asymmetric Key Encryption Algorithms/Key Exchange protocol.
  3. Encrypted Data Transfer (Record): 使用 Private/Symmetric Key Encryption Algorithms

其中, 前兩階段又合稱為”SSL Handshake protocol”, 其目的是要認證 server 並且決定要用來進行實際的資料傳輸之對稱式金鑰, 第三步稱為”SSL Record protocol”, 用意在於傳輸加密資料.

值得注意的是, 這三種階段都有各自要使用的演算法與機制. 在整個 SSL 通訊當中, 會用到對稱式以及非對稱式加密演算法, 並且視情況使用到金鑰交換演算法. Authentication 階段需要使用非對稱式加密演算法, 金鑰交換階段則可以透過非對稱式金鑰加密演算法或是金鑰交換協議, 而最後的加密資料傳輸階段則只會使用對稱式加密演算法.

Authentication Phase

步驟 1–5 是構成 authentication 階段的基本步驟.

Step 1:
Client 送出了一個 client hello 至server端. 這個 hello 訊息包含了一些細節, 如其所支持的 SSL 之最高版本 (這個版號可以是sslv3, tls1.0, tls1.1, tls1.2.). 再來, 也包含了在這個 SSL 版本之下其所支援的所有 cipher suites (密碼套件). 所謂的 cipher suit 就是一種協議與演算法的組合, 這個組合會被用在該 SSL session中.
上圖就是一個 cipher suite 的範例, 可以看成是一個由六個部分所組成的字串:

  • 所使用的傳輸層協議: 其它如 SSL (當然現在幾乎都是TLS了)
  • 會話金鑰(session key)的交換演算法: 其它如 RSA, DH, DHE, 用於決定 client / server 之間在 handshake時要如何進行身份驗證
  • 憑證的 PKI 類型: 其它如 DSS(Digital Signature Standard)
  • 在對實際資料進行加密時所使用的對稱式密碼演算法(批次加密演算法): 其它如 RC4, 3DES, CAMELLIA, ARIA, DES40
  • 對稱式密碼演算法的操作模式: 其它如 CCM, GCM
  • 確保資料完整性的雜湊演算法(訊息鑑別碼演算法): 其它如MD5, SHA2

除了上述的部分, client hello 也包含了要使用哪種資料壓縮方法. 若之後的金鑰交換階段要採用RSA演算法, 則還會再生成一個隨機數, 用於金鑰交換階段生成對稱式金鑰用 (client’s random number).

Step 2:
當收到client hello之後, server 就會準備好一個 server hello 訊息並且將之送回去給 client. 這個訊息中包含了 SSL version, cipher suite, server 支援且同意的資料壓縮方法以及最重要的: Server 的 SSL certificate. 若之後的金鑰交換階段要採用RSA演算法, 則還會再生成一個隨機數, 用於金鑰交換階段生成對稱式金鑰用 (server’s random number).

Server hello 還有一個選填的欄位, 其作用是用來提醒 client 是否需要將 client 的憑證送回給 server. Client certificate 在公開網路中是很罕見的, 但在一些要求高安全性的環境中, 如國防通訊等, 這時候 server 就應該要認證 client.

在 server hello的尾聲, 會有一個 server hello done 的指令來表示這段資訊的結束.

Step 3:
接下來, 就輪到 client 驗證 server 的 SSL 憑證了, 瀏覽器會去看是哪個 CA 簽了這個憑證的, 然後去把這個 CA 的 public key 從瀏覽器的 cert store 中讀出來並且用來驗證憑證中的數位簽章(之前的文章提過, 此處憑證中的數位簽章是 CA 的數位簽章, 就是將網站擁有者的 public key 透過 CA 的 private key 加密後的結果). 若從數位簽章中解出來的 public key 跟 server 同時送來的 public key 是不吻合的, 就表示簽章是不合法的, 瀏覽器就會產生警告. 通常一個不合法的憑證就代表了可能會有 MITM 攻擊的出現.

Step 4:
若 server 有在 server hello 中要求 client 憑證的話, 就會有這一步的出現, 這時候 client 會將其憑證送給 server.

Step 5:
接續前一步驟, server 會在這步驗證 client 的憑證.

到這裡為止, 就算是完成 SSL handshake 裡的 authentication 階段了.

Key Exchange Phase

金鑰交換階段包含了上面流程圖中的第6步到第10步. 這階段最重要的, 就是要產生一個用來在 client 以及 server 之間當作 shared secret 的對稱式金鑰. 要生出這個金鑰有很多方法, 其中, RSA 與 Deffie Hellman 以算法是最常見的金鑰交換演算法.

RSA Key Exchange
首先來看一下透過 RSA 演算法取得金鑰的方式 (這曾經是最常使用的方式之一):

一開始 client 會先生成一個 random number, 並使用 server 的公鑰(包含在 server 寄過來的 SSL 憑證中的一部分) 來加密此 random number (這樣這個 random number 才不會被竊聽), 以作為所謂的 pre-master secret (a.k.a. PMS), 然後把這個 PMS 寄給 sever 端. 在資料傳輸階段進行加密的對稱式金鑰( master secret )就是透過 pre-master secret 以及前面提過的由 client/server 各自提供的 random numbers 所計算出來的. 這個計算的動作不管是在 client 還是 server 都會執行, 以取得共同的 shared key, 因此, master secret 是不會透過網路來傳輸的(因為兩邊都可以擁有計算出金鑰所需的所有元素). 事實上, master secret 是一個由三部分所組成的函數:

  1. Pre-master secret
  2. Client’s random number
  3. Server’s random number

那為什麼要三個數字呢? 因為這樣生成的 secret 亂度才會夠高, 由於 SSL 憑證是靜態的, 所以導入適當的隨機因素以確保協商出來的 secret 之隨機性是有必要的. 在以 RSA 實作金鑰交換的流程中, pre-master secret 本身就是一個隨機數, 再加上在之前的 hello 過程中, 由 client/server 各別生出的隨機數, 就導出了一個具有足夠隨機性的 secret 了.

使用 RSA 作為金鑰交換機制的實作演算法有一個缺點就是其本身是不具有 Perfect Forward Secrecy (PFS)的. PFS 是安全通訊協定中的一個特性, 其可以保護過往的 session 不會在未來的時間點被破解(不論是 secret key 還是 password). 在使用 RSA 的場合下, 一旦攻擊者查出了 shared secret 之後, 其就有辦法解密所有的 SSL 通訊. 這也是為什麼現在比較常見的金鑰交換機制會改用 Deffie hellman 演算法(DH)來實作的原因之一, 因為
DH 演算法不需要像 RSA 一樣進行 PMS key 的交換. Client 以及 server 可以各自獨立地計算出PMS, 這也意味了在 DH 演算法中, 不需要利用 server 的 public key 來進行金鑰交換.

Diffie — Hellman Key Exchange
有時也簡稱為DH演算法, 是一種安全協定. 其可以讓雙方在完全沒有對方任何預先資訊的條件下通過public channel (unsafe channel) 建立起一個金鑰. 這個金鑰可以在後續的通訊中作為對稱金鑰來加密通訊內容. 雖然DH演算法本身是一個匿名(無認證)的金鑰交換協定, 它卻是很多認證協定的基礎, 並且被用來提供傳輸層安全協定的短暫模式中的完備的前向安全性 (forward secrecy) .

講白話一點, DH演算法就是在教你如何”安全地”告訴對方密碼而不用擔心密碼被竊聽. 通過在public channel交換一個資訊, 就可以建立一個可用於在public channel上安全通信的shared secret.
以下是擷取自wiki的DH流程簡圖:

最早提出的這個協定使用如下的離散對數(Discrete Logarithm)公式來做運算:

公式裡的g, x, b, p都是實數, 其中:

  • g: generator
  • p: prime
  • x: 通訊雙方各會有一個, 相異的私鑰

g跟p會是兩邊先溝通好的機制.

有了上述公式以後, 接下來描述DH演算法的運作流程:

  1. Alice與Bob協定使用p = 23以及g = 5
  2. Alice選擇一個secret number(整數), a = 6, 計算A = g^a mod p並傳給Bob : A = 5⁶ mod 23 = 8 (當然不會把6給對方, 而是把 A = 8 給對方)
  3. Bob選擇一個secret number(整數), b = 15, 計算B = g^b mod p然後傳給Alice: B = 5¹⁵ mod 23 = 19 (同上, 只有把 B = 19 給對方)
  4. Alice計算s = B^a mod p: 19⁶ mod 23 = 2
  5. Bob計算s = A^b mod p: 8¹⁵ mod 23 = 2

這邊你可以看到, Alice跟Bob都得到了相同的值, 這是因為在mod p之下, g^ab = g^ba.

或是這樣看:

在這段過程中, 只有a, b, g^ab = g^ba mod p是秘密的, 其餘部分如: p, g, g^a mod p以及g^b mod p都可以在public channel上傳遞. 當Alice跟Bob最後得出了shared secret(s)之後, 他們就可以把這個s當作對稱金鑰來進行雙方的加密通訊, 畢竟這個金鑰只有他們兩個人有辦法知道(所以在加密的部分, 還是屬於對稱式加密). 當然, 為了使這個過程更安全, 必須使用足夠大的a, b以及p, 否則竊聽者可以實驗所有g^ab mod p的可能值(上述例子為p = 23, 所以表示最多總共有22個這樣的值, 這樣a跟b再大也沒意義).若p是一個2~300位的數字, 且a跟b至少有100位長, 那麼除非你手上有量子電腦, 不然大概是不太可能從g, p, g^a mod p中去導出a的. 這個難題就是我們常說的離散對數問題. 這邊要注意的是g可以不用選太大的數字.

如果這樣還太抽象, 可以參考看看下面這張圖, 我覺得這張圖已經把DH演算法的精髓都畫出來了:

以下是從wiki上擷取下來的圖, 可以說明這段過程中通訊雙方以及竊聽者對於所有資訊的能見度:

秘密的整數a和b在對話結束後就會被丟棄, 這就是為什麼DH演算法可以達到完備的前向安全性, 因為私鑰不會存在一個過長的時間而增加洩密的機率.

至於DH演算法的弱點, 基本上就是中間人攻擊, 畢竟在上面的過程中, 我們可以發現沒有任何跟身份驗證有關的手法用來防禦中間人. 故在使用DH演算法時, 最好是要能夠提供一個機制來驗證通訊雙方的身份, 才可以讓此機制更為完善. 譬如說對g^a與g^b進行簽名.

Encrypted Data Transfer (Record) Phase

加密資料傳輸階段, 通常又稱為 record protocol, 這個階段負責處理瀏覽器與網站之間的實際資料傳輸. 要傳輸的資料會透過前面提到的 master secret 以對稱式金鑰加密演算法進行加密. Record protocol 主要會確保兩個特性: 保密性 (confidentiality) 以及完整性 (integrity). 保密性是透過對稱式加密來確保, 完整性則是透過 MAC (Message Authentication Code) 來確保, MAC 值是透過雜湊演算法以及 secret key 計算得來的.

下圖說明了應用程式的資料是如何傳輸的:

  1. 要被傳輸的資料會被分成多個區塊, 稱為 fragments.
  2. 每一個 fragment 都會經由壓縮演算法來進行壓縮.
  3. MAC 值被計算出來, 並且被附加在已經壓縮的 fragment 之後.
  4. 使用 secret key 對 fragment 進行加密.
  5. 在加密過後的 fragment 之前加上 SSL Record Header.

以上就是 SSL Record Protocol 的詳細流程, 其中, 關於最後一步的 SSL Record Header, 大概有以下內容:

  • Byte 0 = SSL record type
    SSL3_RT_CHANGE_CIPHER_SPEC 20 (x’14')
    SSL3_RT_ALERT 21 (x’15')
    SSL3_RT_HANDSHAKE 22 (x’16')
    SSL3_RT_APPLICATION_DATA 23 (x’17')
  • Bytes 1–2 = SSL version (major/minor)
    SSL3_VERSION x’0300'
    TLS1_VERSION x’0301'
  • Bytes 3–4 = Length of data in the record (excluding the header itself). Max is 16384 (16K).
  • Byte 5 = Handshake type
    SSL3_MT_HELLO_REQUEST 0 (x’00')
    SSL3_MT_CLIENT_HELLO 1 (x’01')
    SSL3_MT_SERVER_HELLO 2 (x’02')
    SSL3_MT_CERTIFICATE 11 (x’0B’)
    SSL3_MT_SERVER_KEY_EXCHANGE 12 (x’0C’)
    SSL3_MT_CERTIFICATE_REQUEST 13 (x’0D’)
    SSL3_MT_SERVER_DONE 14 (x’0E’)
    SSL3_MT_CERTIFICATE_VERIFY 15 (x’0F’)
    SSL3_MT_CLIENT_KEY_EXCHANGE 16 (x’10')
    SSL3_MT_FINISHED 20 (x’14')
  • Bytes 6–8 = Length of data to follow in this record
  • Bytes 9-n = Command-specific data

HTTPS的本質

這篇文章已經把 HTTPS 通訊的整個流程大概描述了一次, 所以 HTTPS 的本質到底是什麼呢? 我們可以這樣解讀: HTTPS 就是在 HTTPS connection 發起之前, 先透過 SSL/TLS 協議來協調 client/server, 使兩邊都可以產生出一個基於對稱式金鑰加密演算法的 secret. 有了這個 secret, 就可以在普通的 HTTP 協議中傳輸經過 secret 加密過後的資料內容. 因為這個 secret 是安全的, 所以被加密的內容也就是安全的了.

References

--

--

Carl

Stand for something or you will fall for anything.