簡介 HTTPS / TLS 安全通訊協議


HTTPS 也稱 HTTP over TLSHTTP over SSLHTTP Secure,是透過計算機網路安全 通訊協議 (Protocol)

摘要密碼學與資訊安全 整理了部分的關於 TLS 協議的資料,本文重新整理我自己對於 HTTPS 這個通訊協議的理解。


How SSL Works?

整體來看看 SSL/TLS 是怎麼運作的。

How SSL Works?

圖中包含了幾個角色:

  • Certificate Authoriy (CA): 數位憑證認證機構,是負責發放和管理 數位憑證 的權威機構。
  • Browser Vendor: 瀏覽器的供應者,像是 Google、Microsoft、Apple
  • Client App: 目標瀏覽的應用程式
  • Web Server: 網站服務器

整個流程如下:

  1. CA (Godaddy): 發一張 root certificate 給所有 browser 開發者
  2. Browser Vendor (Google, Mozilla): root certificate 會包在 App (ex 瀏覽器) 發布給使用者。
  3. CSR (certificate signing request): 瀏覽器對 CA 發出 CSR 請求
    • 目的是針對目前 WebSite 的 Domain 做認證
  4. CA 回傳簽可的憑證 (Signed Certificate)
    • 代表 WebSite Domain 的合法性
  5. Client App (browser) 對 Web Server 發出請求
  6. Web Server 回傳請求給 Client App
  7. Client App 驗證 WebSite 的 Domain Certificate

SSL Communication 詳述

下圖是 SSL 整個通訊協議過程的流程圖:

SSL Communication Flow Diagram

  • 階段一 (Authentication):使用 Public / Asymmetric Key Encryption Algorithms.
    • Step 1: Client 送出 Hello 訊息到 Server
    • Step 2: Server 收到 Hello 後回覆 Hello 訊息
    • Step 3: Client 驗證 Server 回傳的 SSL Certificate
    • Step 4: (Optional) Client 傳送 SSL Certifiate 給 Server
    • Step 5: (Optional) Server 驗證 Client 回傳的 SSL Certifiate
  • 階段二 (Key Exchange):使用 Public / Asymmetric Key Encryption Algorithms/Key Exchange protocol.
    • Step 6: Client 送出 Key Exchange 的請求
    • Step 7: 改變 Cipher Spec
    • Step 8: Client 端完成請求
    • Step 9: Server 端依照請求,改變 Cipher Spec
    • Step 10: Server 端完成請求
  • 階段三 (Encrypted Data Transfer):使用 Private / Symmetric Key Encryption Algorithms
    • Step 11: 使用對稱式加密傳輸資料。

前面階段一、二 稱 SSL Handshake Protocol,主要目的是認證 Server 是否合法,進而決定資料傳輸過程使用的對稱式金鑰;階段三則稱為 SSL Record Protocol,主要目的就是在安全的傳輸過程,使用 對稱式加密演算法 傳輸資料。


階段一:Authentication (Handsharke)

這個階段在 公開傳輸 的過程,使用 非對稱加密演算法

  • Step 1: Client 送出 Hello 到 Server,包含以下訊息:
    1. SSL Version: 版本號碼可以是 sslv3, tls1.0, tls1.1, tls1.2
    2. Cipher Suites: 使用在 TLS 時的 演算法集合名稱,詳細後面描述
    3. 如果 金鑰交換階段 要使用 RSA ,那麼會再產生一個 Client Random Number.
  • Step 2: Server 準備回給 Client 的 Hello 訊息,其中包含了:
    1. SSL Version
    2. Cipher Suites
    3. 支援、且同意的資料壓縮方法
    4. SSL Certificate: 這是整個步驟中最重要的資訊。
      • 如果之後 金鑰交換階段 使用 RSA ,則會再產生一個隨機數 (Server Random Number),用在金要交換階段生成對稱金鑰用。
    5. (optional) Client Certificate
    6. Hello Done:
  • Step 3:
    1. Client 收到 Server 回傳的 SSL Certificate,就會檢查是哪個 CA 簽發的憑證
    2. 然後從 Browser 的 Cert Store 取出對應的數位簽章,從中取得 Public Key,與 SSL Certificate 的 Public Key 比對。
    3. 如果有問題,表示發生 中間人攻擊, Man-in-the-middle attack (MITM)
  • Step 4: (optional) Client 發送 Certificate 給 Server
  • Step 5: (optional) Server 驗證 Client 的 Ceritifcate

Cipher Suites

Step 1 Client 送出 Hello 訊息時,依照 SSL Version 的訊息,會包含一些此版本支援的 協議與演算法組合,這個組合稱為 Cipher Suites,這個組合會被用在整個 SSL Session 過程中。Cipher Suites 的名稱大概長得像下面這樣:

  • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
  • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  • TLS_RSA_WITH_AES_128_GCM_SHA256

上述的 Cipher Suite 名稱在 RFC 有標準定義命名規則,上述的範例是 TLS 使用的標準規則,定義在 RFC 2246, TLS v1.0, RFC 4346, TLS v1.1, RFC 5246, TLS v1.2, and RFC 8446, TLS v1.3

命名格式如下:

L1_L2_L3_WITH_L4_L5_L6

  • L1: 使用哪一個傳輸層通訊協議,有 TLS、SSL。
  • L2: 描述使用哪個 Key Exchange 演算法,像是 RSA、DH (Diffie–Hellman)
    • ECDHE 全名 Elliptic Curve Diffie-Hellman Ephemeral,中文 橢圓曲線迪菲-赫爾曼密鑰交換,是一種 匿名密鑰協議 (Key-agreement protocol)
    • 這是 Diffie–Hellman key exchange 的變種,採用 橢圓曲線密碼學 來加強性能與安全性。
    • ECDH 則是
  • L3: 交握過程的認證機制
    • RSA
  • L4: session cipher,加密的 Size
    • 範例:AES_128
  • L5: 對稱式加密演算法法的操作模式
    • GCM type of encryption (cipher-block dependency and additional options)
  • SHA (SHA2)hash function. For a digest of 256 and higher. Signature mechanism. indicates the message authentication algorithm which is used to authenticate a message.
  • 256 Digest size (bits).

附註:Cipher Suite 的命名規則,在 RFC 與部分實作有所差異,OpenSSL and s2n, c99 則使用另一種命名方式。相關對照表可以參考 Supported protocols and ciphers between viewers and CloudFront 的整理。

下圖是 AWS ELB / CLB 中的 SSL Cipher Suite 設定截圖:

更多 ELB Security Policy 定義參閱: Predefined SSL security policies for Classic Load Balancers


階段二:Key Exchange

同階段一,也是在 公開傳輸 的過程,使用 非對稱加密演算法。這個階段的目的:

產生一個用來在 階段三 資料交換時,使用的 對稱式加密演算法對稱式金鑰 (Shared Secret)

在一個公開透明的傳輸通道要產生金曜、然後傳輸,最常見的方法是 RSA 或者 Deffie Hellman 演算法。

  • Step 6: Client 送出 Key Exchange 的請求
  • Step 7: 改變 Cipher Spec
  • Step 8: Client 端完成請求
  • Step 9: Server 端依照請求,改變 Cipher Spec
  • Step 10: Server 端完成請求

RSA Key Exchange

  • Pre-master secret: 使用 RSA 取得金鑰,那麼在 Step1 就會產生 Random Number,然後使用 Server 憑證裡的公鑰加密,這個 Random Number 稱為 Pre-master secret (PMS)
  • Client's Random Number: Client 端產生的一組隨機碼
  • Server's Random Number: Server 端產生的一組隨機碼

透過這三個數字的隨機性,就可以產生 資料傳輸階段 時,對稱式加密演算法 所需要的 加密金鑰 (Master Secret)

但是用 RSA 並不具備 PFS 特性,所以現在大多使用 DH 演算法。

Forward Secrecy

中文翻譯成 向前保密,有時候也稱為 完全向前保密 (Perfect Forward Secrecy, PFS),是密碼學中通訊協議的安全屬性。

TLS 基於 DHE (迪菲-赫爾曼金鑰交換) 演算法,就滿足 PFS 的特性,以下是滿足的演算法:

  • DHE-RSA
  • DHE-DSA
  • DHE-ECDSA

基於 ECDHE (橢圓曲線迪菲-赫爾曼金鑰交換) 的安全通訊,包含了:

  • ECDHE-RSA
  • ECDHE-ECDSA

更多參閱 Wikipedia 說明: Forward Secrecy

Diffie-Hellman Key Exchange

大多時候簡稱 DH 演算法,是一種安全協議,主要目的:

雙方在沒有任何預先條件之下,透過公開的管道 (Public Channel, Unsafe) 建立一個金鑰,這個金鑰可以在後續的通訊過程作為加密金鑰來加密資料。

與 RSA 不一樣的是,DH 演算法具備了 向前安全性 (Forward Secrecy),所以被廣泛運用在通訊傳輸的安全加密。

DH 演算法詳細推演過程,參閱 Wikipedia

DH 演算法的弱點就是 中間人攻擊,因為整個演算法並沒有跟 身份驗證 有關的資訊,所以理想的做法就是要有個機制可以做身份識別,這也就是為什麼用自簽憑證的 HTTPS 瀏覽器會看出現警告訊息的原因。


階段三:Encrypted Data Transfer / Record Protocol

進入資料傳輸階段,這個階段也稱為 Record protocol,使用 對稱加密演算法 加密瀏覽器與伺服器之間傳輸的資料。這個過程必須滿足以下特性:

  1. 保密性 (Confidentiality): 透過對稱式加密達到保密性,使用之前提到的 Master Secret 做資料加密。
  2. 完整性 (Integrity): 透過 MAC (Message Authentication Code) 確認,MAC 則是透過 Hash 演算法計算得來。

下圖是 Record Protocol 的結構:


圖片來源:SSL Record Protocol

結構與流程說明如下:

  1. Application Data: 應用程式資料會被拆分成若干份 Fragment
  2. Fragment: 每個傳輸資料會被拆分成幾個區塊後,個別傳送,這個區塊稱為 Fragment
    • 每個 Fragment 會經過壓縮演算法進行資料壓縮
  3. MAC: 用來確認每個 Fragment 的完整性驗證碼
    • 每個壓縮過後的資料,透過 Hash 計算出 MAC 值
    • 這個 MAC 值附加在壓縮資料之後
  4. Encrypt: 取得 Fragment 的 MAC 之後,使用 Secret Key 加密這兩個
  5. SSL Record Header: 最後附上 Record Header

Lab

為了瞭解 整個 HTTPS / TLS 通訊過程真實的狀況,我用 Wireshark 抓了一些封包,紀錄整個 Handshark 過程的資訊,與後面的整理比較。

下圖是透過 Browser Brave 連線 199.232.192.134 這個網站,使用 Wireshark 3.4.7-0-ge42cbf6a415 在 macOS 10.15.7 抓的封包:

階段一:Client Hello

Client (Browser) to Server,在 Client Hello 部分有以下資訊:

  • Handshake Type: Client Hello (1)
  • Version: TLS 1.2 (0x0303)
  • Random: 7bcc7dce161a90f5fe5c83aaea001fb9cc3dcf532be85448534a4d0ef3d7578e
  • Session ID: 8bbaaaff25ea8066c42ebc05f9059b310c27dbb86b973439d88bda2405613682
  • Cipher Suites (16 suites)

階段一、二:Server Hello, Change Cipher Spec, Encrypted Handshake Message

Server to Client,在 Server Hello 部分可以看出以下資訊:

  • Handshake Type: Server Hello (2)
  • Version: TLS 1.2 (0x0303)
  • Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
  • Random: b3b00f857658ec49606ca3bcd3aaae6768b1b045898731e3675e0dc866bd11fa
    • Cipher Suite 使用 ECDHE_RSA
  • Compression Method: null (0)

Client (Browser) to Server:

Wireshark 的 Filers

一些使用 Wireshark 過程的記錄:

Filter:

  • ip.addr == 142.251.43.19 && tls.record.version == 0x0303
  • ip.addr == 142.251.43.19 && ssl.record.version == 0x0303

其中:

  • 0x0300 SSL 3.0
  • 0x0301 TLS 1.0
  • 0x0302 TLS 1.1
  • 0x0303 TLS 1.2
  • 0x0304 TLS 1.3

參考:Wireshark - Why TLS version is different in Record Layer and Handshake Protocol

透過 openssl 了解 TLS 狀況

整個 TLS 的過程,大多都可以透過 openssl 做實驗,以下整理可以做的動作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
~$ openssl version
LibreSSL 2.8.3

# 取得 openssl 支援的 Cipher Suite 的資訊
~$ openssl ciphers -v
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384
ECDHE-ECDSA-AES256-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA1

... 略 ...

ECDHE-RSA-DES-CBC3-SHA SSLv3 Kx=ECDH Au=RSA Enc=3DES(168) Mac=SHA1
ECDHE-ECDSA-DES-CBC3-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=3DES(168) Mac=SHA1
EDH-RSA-DES-CBC3-SHA SSLv3 Kx=DH Au=RSA Enc=3DES(168) Mac=SHA1
DES-CBC3-SHA SSLv3 Kx=RSA Au=RSA Enc=3DES(168) Mac=SHA1


# 使用 OpenSSL 查詢網站伺服器的所有憑證與 TLS 連接資訊,預設會走 TLS v1.3
❯ openssl s_client -connect rickhw.github.com:443

CONNECTED(00000006)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA
verify return:1
depth=0 C = US, ST = California, L = San Francisco, O = "GitHub, Inc.", CN = www.github.com
verify return:1
---
Certificate chain
0 s:/C=US/ST=California/L=San Francisco/O=GitHub, Inc./CN=www.github.com
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIHMDCCBhigAwIBAgIQAkk+B/qeN1otu8YdlEMPzzANBgkqhkiG9w0BAQsFADBw
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNz

... 略 ...

YaRIpRMRdj4stG6CkPJpfSauWa19kReZ6hTQR5f89L6x50us7GuWlmH6EmVFIbhf
9EO02QA3CcU7bE1iLWMHmKcU6ythmgsvNRU5TikxvF77JFv7n1/y8GLrprmKpB6Q
Df4PA8S9ROX9Rzgwe3KTIM6qeKU=
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=San Francisco/O=GitHub, Inc./CN=www.github.com
issuer=/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
---
No client certificate CA names sent
Server Temp Key: ECDH, X25519, 253 bits
---
SSL handshake has read 3673 bytes and written 289 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
Session-ID: 26C9C570ABA03D7D03BADA74248CEF20FDD5279B6A9EAA4D5128E072EF587E5F
Session-ID-ctx:
Master-Key: 49196F3EE337F88CDBF64E8EE41DF9BC283DAAD6C5E2A9C7544933A3847FC1904B15842413AE6A15FF2FDB328C9BD37B
TLS session ticket lifetime hint: 7200 (seconds)
TLS session ticket:
0000 - d1 d1 01 52 63 e8 4d 9d-27 06 48 21 bc 74 06 8d ...Rc.M.'.H!.t..
0010 - a6 63 66 6f d3 0e a9 94-31 a4 92 17 27 6a 56 cd .cfo....1...'jV.
0020 - 99 5f cc da 8c 21 f1 75-fc 62 45 8a d9 95 ef d4 ._...!.u.bE.....
0030 - 1d 05 fd 6d fb 8b 01 7e-29 5e 43 85 16 a2 59 73 ...m...~)^C...Ys
0040 - 4a a7 6d f4 ee e9 1d 05-76 f9 3a ac 54 0d b7 13 J.m.....v.:.T...
0050 - 00 73 f7 56 cb ff 96 c8-b6 05 1e 79 65 df 2f 51 .s.V.......ye./Q
0060 - 55 c1 2d fb b8 9e 29 81-84 1f 74 24 67 b6 05 3b U.-...)...t$g..;
0070 - 0e ae 4d 9a b6 80 b4 21-be 37 4b 3a 6a 66 fb 51 ..M....!.7K:jf.Q
0080 - bd 3c d4 5b 58 f2 8e 90-a4 8a c6 ac d8 db f1 25 .<.[X..........%
0090 - ba 6c 15 e8 af 7b c5 e8-82 98 13 db 9e 26 07 5a .l...{.......&.Z

Start Time: 1629555199
Timeout : 7200 (sec)
Verify return code: 0 (ok)

## 指定 TLS v1.2
~$ openssl s_client -connect rickhw.github.com:443 -tls1_2

... 略 ...
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
Session-ID: 210CB9C73B2ACB4C91A6A07A753342FEB900AB7E6245DAD438689E8FA3FBFDED
Session-ID-ctx:
Master-Key: 28A18A970DD37D9B84F79ED46D027998ECF2DCF9EDD01A376A7A0A8B4F57D15053789B1A63B720362A6F4AED7189C020
TLS session ticket lifetime hint: 7200 (seconds)
TLS session ticket:
0000 - d1 d1 01 52 63 e8 4d 9d-27 06 48 21 bc 74 06 8d ...Rc.M. .H!.t..
0010 - 7d 09 ff 8d 7a 2f 85 ac-e7 bc 38 33 7d 37 f2 f6 }...z/....83}7..
0020 - 9e 5c c2 69 e7 d8 5e 63-d6 b8 72 b1 6f 57 6a 42 .\.i..^c..r.oWjB
0030 - 0e da 75 21 f3 c0 5d 01-65 07 bf 91 bd ba fb a8 ..u!..].e.......
0040 - 56 db 7f 82 b9 bd 23 26-b2 8b 53 e4 1e 99 7b e1 V.....#&..S...{.
0050 - 3f 9e 45 05 3e d2 a7 f8-ae 0a df 00 48 75 70 fd ?.E.>.......Hup.
0060 - b2 e9 21 0a c8 a7 4d 66-65 f8 9c 9f b2 c2 3c c1 ..!...Mfe.....<.
0070 - 52 5d 06 9b 5e 22 67 b2-36 a2 c0 3f bf d7 6b 3e R]..^"g.6..?..k>
0080 - 22 f0 3f 6b 3c 59 0a a6-2d 85 00 19 11 81 bb 7f ".?k<Y..-.......
0090 - b4 7b a6 97 96 9f 00 42-8a ae e3 a3 32 9b 8d ff .{.....B....2...

Start Time: 1629555327
Timeout : 7200 (sec)
Verify return code: 0 (ok)
---

除了 openssl,也可以使用 cURL:

1
2
3
4
5
6
7
8
9
10
11
~$ curl --version
curl 7.64.1 (x86_64-apple-darwin19.0) libcurl/7.64.1 (SecureTransport) LibreSSL/2.8.3 zlib/1.2.11 nghttp2/1.39.2
Release-Date: 2019-03-27
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS GSS-API HTTP2 HTTPS-proxy IPv6 Kerberos Largefile libz MultiSSL NTLM NTLM_WB SPNEGO SSL UnixSockets

## 指定 TLS v1.2, Cipher Suite: ECDHE-ECDSA-AES128-GCM-SHA256
~$ curl -s -S -v -o /dev/null \
--tls-max 1.2 \
--ciphers ECDHE-ECDSA-AES128-GCM-SHA256 \
https://rickhw.github.com

結語

想設計出一個安全的通訊協議,最好的方法,就是參考現在在線上運行多年的標準協議。

那些我們使用多年,卻完全不知道怎麼運做的協議,越是經的起考驗、值得研究的。很久以前就想整理關於 HTTPS / TLS 通訊協議的知識,研究過整個 TLS 協議之後,對於設計安全通訊協議算是有初步基礎的認識,過程中也更加強了整理 摘要密碼學與資訊安全 一文中不解的部分。

近利用一些瑣碎時間,片段的把資訊組起來,找了很多資料、抓封包分析了解。探索過程其實是很享受、且有趣的,而且更加地知道自己的不足,更加知道前人努力的完整性。

資訊安全 一直以來都是 動詞,但是要具備 能力 (Ability) 執行這些動作,所要具備的 領域專業知識 (Know How)技能 (Skills) 是一個都不能少的,否則就只是紙上談兵,說空話的江湖郎中。在整理 AWS KMS 以及 Secret Management 的時候,就覺得應該往前推把 基礎密碼學 做一些複習與研究,彌補自己對於這些知識的不足。而在研讀密碼學的過程,覺得應該要與實務結合,過程中因為時事,整理了 Data Encryption 的概念 (Data in Transit、at Rest、in Used) ,岔到了資訊安全去了。後來覺得要能夠精準掌握這些密碼覺得應用,還是應該從掌握協議設計切入,所以選擇了現金網路通訊最重要的安全通訊協議 TLS 切入,所以就有了這一篇 簡介 HTTPS / TLS 安全通訊協議 整理。

網路上其實有很多整理很好的文章,本文剛開始是參考 那些關於SSL/TLS的二三事(九) — SSL (HTTPS) Communication 為起點,過程中以此延伸找尋更多資料,更是實際從抓封包、夠過 openssl 實際應用,得到驗證。

這只是開始,還有很多要補充以及學習的!


延伸閱讀

站內文章

參考資料

RFC

Wikipedia




Comments