目錄
03-4. HTTPS 握手過程
⏱️ 閱讀時間: 15 分鐘 🎯 難度: ⭐⭐⭐ (中等)
🎯 本篇重點
深入理解 HTTPS 握手的完整流程、TLS 1.2 和 TLS 1.3 的差異、握手過程中的每個步驟細節,以及如何優化握手效能。
🤔 什麼是 HTTPS 握手?
TLS Handshake = 建立安全連線前的「協商過程」
一句話解釋: HTTPS 握手就像是兩個人見面前先確認身份、交換密碼本、約定暗號,確保之後的對話只有彼此能聽懂。
🤝 用見面交換情報來比喻握手
特務接頭
場景:兩個特務要交換機密情報
步驟 1:確認身份(憑證驗證)
特務A:報上名來
特務B:我是特務B,這是我的證件 🎫(憑證)
特務A:檢查證件...✅ 確認是真的
步驟 2:交換密碼本(金鑰交換)
特務A:產生一本密碼本 📖
特務A:用特務B的公開加密箱鎖住密碼本
特務B:用私人鑰匙打開加密箱
→ 雙方都有相同的密碼本了
步驟 3:開始加密通訊(對稱加密)
特務A:用密碼本加密情報
特務B:用密碼本解密情報
→ 旁人聽不懂
特性:
- 確認身份(防止冒充)
- 安全交換密碼本(防止竊聽)
- 加密通訊(防止洩密)🔄 完整的 HTTPS 連線流程
概覽
【第 1 步:TCP 三次握手】
建立 TCP 連線(80 毫秒)
【第 2 步:TLS 握手】
建立安全連線(100-200 毫秒)
【第 3 步:HTTP 請求/回應】
加密的 HTTP 通訊
【第 4 步:關閉連線】
TCP 四次揮手 or Keep-Alive
總延遲:
TCP (1-RTT) + TLS (1-2 RTT) + HTTP (1-RTT)
= 3-4 RTT ≈ 200-400ms📋 TLS 1.2 握手流程(詳細版)
完整流程(2-RTT)
客戶端 伺服器
【第 1 次往返(1-RTT)】
ClientHello ─────────────────────→
- TLS 版本:TLS 1.2
- 隨機數(Random_C)
- 支援的加密套件清單:
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- ...
- 支援的壓縮方法
- 擴充欄位(SNI、ALPN)
←───────── ServerHello
- 選擇的 TLS 版本:TLS 1.2
- 隨機數(Random_S)
- 選擇的加密套件
- 選擇的壓縮方法
←───────── Certificate
- 伺服器憑證鏈 📜
- 網站憑證 + 中繼 CA 憑證
←───────── ServerKeyExchange
- 金鑰交換參數
- ECDHE 公鑰
- 簽章(證明公鑰真實性)
←───────── ServerHelloDone
- 伺服器訊息結束
【客戶端驗證】
1. 驗證憑證有效性 ✅
2. 檢查憑證鏈 ✅
3. 驗證簽章 ✅
【第 2 次往返(2-RTT)】
ClientKeyExchange ────────────────→
- ECDHE 公鑰
- 用伺服器公鑰加密的預主密鑰
ChangeCipherSpec ─────────────────→
- 通知切換到加密模式
Finished ─────────────────────────→
- 加密的握手訊息摘要
- 驗證握手過程完整性
←───────── ChangeCipherSpec
- 伺服器切換到加密模式
←───────── Finished
- 加密的握手訊息摘要
【握手完成】✅
雙方計算出「主密鑰」(Master Secret)
Random_C + Random_S + 預主密鑰 → 主密鑰
【開始加密通訊】
Application Data ←────────────────→
- 所有後續 HTTP 通訊都加密詳細步驟解析
1️⃣ ClientHello
內容:
- TLS Version: TLS 1.2
- Random: [32 bytes random data]
- 時間戳 (4 bytes)
- 隨機數 (28 bytes)
- Session ID: (恢復會話用)
- Cipher Suites: (支援的加密套件)
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- ...
- Compression Methods: null
- Extensions:
- server_name (SNI): www.example.com
- supported_groups: x25519, secp256r1, secp384r1
- signature_algorithms: rsa_pss_rsae_sha256, ecdsa_secp256r1_sha256
- application_layer_protocol_negotiation (ALPN): h2, http/1.1
作用:
- 告訴伺服器客戶端支援的功能
- 包含隨機數(防重放攻擊)2️⃣ ServerHello
內容:
- TLS Version: TLS 1.2
- Random: [32 bytes random data]
- Session ID: [session id]
- Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (選擇的套件)
- Compression Method: null
作用:
- 確認使用的 TLS 版本
- 選擇加密套件
- 提供伺服器隨機數3️⃣ Certificate
內容:
憑證鏈:
- 網站憑證(www.example.com)
- 中繼 CA 憑證
- (可選)根 CA 憑證
作用:
- 證明伺服器身份
- 提供公鑰用於後續加密4️⃣ ServerKeyExchange
內容(ECDHE):
- Curve Type: named_curve
- Named Curve: x25519
- Public Key: [ECDHE public key]
- Signature Algorithm: rsa_pss_rsae_sha256
- Signature: [RSA signature]
作用:
- 提供 ECDHE 臨時公鑰
- 用憑證私鑰簽署(證明公鑰真實性)5️⃣ ClientKeyExchange
內容(ECDHE):
- Public Key: [ECDHE public key from client]
作用:
- 提供客戶端 ECDHE 公鑰
- 雙方計算共享密鑰(Pre-Master Secret)
計算:
客戶端:client_private_key + server_public_key → shared_secret
伺服器:server_private_key + client_public_key → shared_secret
→ 相同的 shared_secret!6️⃣ ChangeCipherSpec
內容:
- 單一訊息:0x01
作用:
- 通知對方:後續訊息都將加密7️⃣ Finished
內容:
- verify_data: PRF(master_secret, "finished", Hash(handshake_messages))
作用:
- 驗證握手過程完整性
- 確認雙方計算出相同的密鑰
- 第一個加密的訊息🚀 TLS 1.3 握手流程(簡化版)
完整流程(1-RTT)
客戶端 伺服器
【第 1 次往返(1-RTT)】
ClientHello ─────────────────────→
- TLS 版本:TLS 1.3
- 隨機數(Random_C)
- 支援的加密套件清單
- Key Share(直接包含公鑰)← 新增!
- x25519: [client public key]
- 支援的簽章演算法
- SNI
←───────── ServerHello
- TLS 版本:TLS 1.3
- 隨機數(Random_S)
- 選擇的加密套件
- Key Share(伺服器公鑰)
←───────── EncryptedExtensions
(以下訊息都加密)
←───────── Certificate
- 伺服器憑證
←───────── CertificateVerify
- 憑證簽章驗證
←───────── Finished
- 握手完成訊息
【客戶端驗證憑證】
Finished ─────────────────────────→
- 握手完成訊息
【握手完成】✅
Application Data ←────────────────→
- 開始加密通訊
改進:
✅ 只需 1-RTT(TLS 1.2 需要 2-RTT)
✅ 握手訊息大多加密(只有 ClientHello/ServerHello 明文)
✅ 強制前向保密(只支援 ECDHE)
✅ 移除不安全的加密套件TLS 1.3 的關鍵改進
1. 1-RTT(更快)
TLS 1.2(2-RTT):
ClientHello →
← ServerHello + Certificate + ...
ClientKeyExchange + Finished →
← Finished
開始通訊
TLS 1.3(1-RTT):
ClientHello + KeyShare →
← ServerHello + KeyShare + Certificate + Finished
Finished →
開始通訊
時間差:
TLS 1.2:2 × RTT ≈ 200ms
TLS 1.3:1 × RTT ≈ 100ms
→ 快 100ms2. 0-RTT(更更快)
TLS 1.3 支援 0-RTT 恢復會話:
第一次連線:
(正常 1-RTT 握手)
伺服器 → 客戶端:Session Ticket
第二次連線(同一伺服器):
ClientHello + Early Data →
(不等握手完成,直接發送 HTTP 請求)
→ 完全沒有額外延遲!
注意:
0-RTT 有重放攻擊風險
只適合冪等操作(GET)
不適合 POST/PUT/DELETE3. 加密握手訊息
TLS 1.2:
大部分握手訊息明文
→ 可能洩露敏感資訊(SNI、ALPN)
TLS 1.3:
從 ServerHello 之後都加密
→ 只有 ClientHello/ServerHello 明文
→ 更好的隱私保護4. 簡化加密套件
TLS 1.2:
支援數十種加密套件
包含許多不安全的選項
例:
- TLS_RSA_WITH_AES_128_CBC_SHA(不支援前向保密)
- TLS_RSA_WITH_RC4_128_SHA(RC4 不安全)
TLS 1.3:
只支援 5 種安全套件
強制前向保密(ECDHE)
- TLS_AES_128_GCM_SHA256
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
- TLS_AES_128_CCM_SHA256
- TLS_AES_128_CCM_8_SHA256
→ 移除所有不安全的選項🔍 關鍵概念詳解
隨機數(Random)的作用
為什麼需要隨機數?
1. 防止重放攻擊(Replay Attack)
駭客:記錄完整的握手過程
駭客:重新發送相同的訊息
→ 如果沒有隨機數,會產生相同的密鑰
→ 駭客可以解密
有隨機數:
每次握手的隨機數都不同
→ 每次產生不同的密鑰
→ 重放攻擊無效
2. 增加熵(Entropy)
Random_C + Random_S → 更隨機的密鑰
產生主密鑰:
Master Secret = PRF(
Pre-Master Secret,
"master secret",
Random_C + Random_S
)PRF(偽隨機函數)
PRF = Pseudo-Random Function
作用:
從少量秘密(Pre-Master Secret)
產生大量密鑰材料
TLS 1.2 PRF:
基於 HMAC-SHA256
用途:
從 Pre-Master Secret 產生:
1. Master Secret
2. Client Write Key(客戶端加密密鑰)
3. Server Write Key(伺服器加密密鑰)
4. Client Write IV(初始向量)
5. Server Write IV
6. Client Write MAC Key
7. Server Write MAC Key
→ 一個秘密衍生出所有需要的密鑰SNI(Server Name Indication)
問題:
一個 IP 位址可能有多個網站
TCP 連線時還不知道要訪問哪個網站
伺服器不知道要提供哪個憑證
範例:
伺服器 IP: 192.168.1.100
├─ www.example1.com
├─ www.example2.com
└─ www.example3.com
客戶端連線到 192.168.1.100
伺服器:不知道要提供哪個憑證?
SNI 解決方案:
ClientHello 包含 SNI 擴充:
server_name: www.example1.com
伺服器:
收到 SNI → 知道是 www.example1.com
→ 提供對應的憑證
缺點:
SNI 是明文(TLS 1.2)
→ ISP 可以看到你訪問的網站
→ 隱私問題
TLS 1.3 改進:
Encrypted SNI (ESNI)
→ 加密 SNI,保護隱私ALPN(Application-Layer Protocol Negotiation)
作用:
協商應用層協定
ClientHello:
ALPN: h2, http/1.1
ServerHello:
ALPN: h2
→ 雙方同意使用 HTTP/2
好處:
- 避免額外的協商往返
- 在 TLS 握手中完成
- 支援 HTTP/2、HTTP/3⚡ 握手效能優化
1. Session Resumption(會話恢復)
問題:
每次連線都要完整握手
→ 耗時
解決:
第一次連線:完整握手 + Session ID
伺服器 → 客戶端:Session ID: abc123
第二次連線:
ClientHello + Session ID: abc123 →
← ServerHello + Session ID: abc123
← ChangeCipherSpec + Finished
Finished →
開始通訊
縮短為:1-RTT(省略憑證傳輸和金鑰交換)
TLS 1.2:Session ID 或 Session Ticket
TLS 1.3:Session Ticket(PSK)2. OCSP Stapling
問題:
驗證憑證是否被撤銷
客戶端 → OCSP 伺服器:查詢憑證狀態
→ 增加延遲(額外的 DNS + TCP + HTTP 請求)
OCSP Stapling 解決:
伺服器定期從 OCSP 伺服器取得憑證狀態
伺服器 → 客戶端:憑證 + OCSP 回應
優點:
✅ 不需要額外請求
✅ 更快(省略 OCSP 查詢)
✅ 更好的隱私(客戶端不直接聯繫 OCSP)
Nginx 設定:
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/chain.pem;3. TLS False Start
作用:
客戶端在收到 Finished 前就開始發送應用資料
TLS 1.2:
ClientKeyExchange + Finished + HTTP Request →
(不等伺服器 Finished)
省略:0.5 RTT
要求:
- 必須是強加密套件
- 必須支援前向保密(ECDHE)
- TLS 1.2+
TLS 1.3:
已內建(握手訊息和應用資料可以同時發送)4. HTTP/2 Server Push
作用:
伺服器主動推送資源
傳統:
1. 客戶端:GET /index.html
2. 伺服器:<html>... <link rel="stylesheet" href="style.css">
3. 客戶端:解析 HTML → 發現需要 style.css
4. 客戶端:GET /style.css
5. 伺服器:返回 style.css
HTTP/2 Server Push:
1. 客戶端:GET /index.html
2. 伺服器:
- 推送:style.css
- 推送:script.js
- 返回:index.html
省略:多次往返🛠️ 實際觀察握手過程
使用 Wireshark
步驟:
1. 打開 Wireshark
2. 選擇網路介面
3. 過濾器:ssl or tls
4. 訪問 https://www.google.com
5. 查看封包
可以看到:
├─ Client Hello
├─ Server Hello
├─ Certificate
├─ Server Key Exchange
├─ Server Hello Done
├─ Client Key Exchange
├─ Change Cipher Spec
├─ Encrypted Handshake Message
└─ Application Data (加密的 HTTP)使用 OpenSSL
# 查看握手過程
openssl s_client -connect www.google.com:443 -state
# 輸出:
SSL_connect:before SSL initialization
SSL_connect:SSLv3/TLS write client hello
SSL_connect:SSLv3/TLS read server hello
SSL_connect:SSLv3/TLS read server certificate
SSL_connect:SSLv3/TLS read server key exchange
SSL_connect:SSLv3/TLS read server done
SSL_connect:SSLv3/TLS write client key exchange
SSL_connect:SSLv3/TLS write change cipher spec
SSL_connect:SSLv3/TLS write finished
SSL_connect:SSLv3/TLS read change cipher spec
SSL_connect:SSLv3/TLS read finished
# 查看握手時間
time openssl s_client -connect www.google.com:443 < /dev/null
# 測試特定 TLS 版本
openssl s_client -connect www.google.com:443 -tls1_2
openssl s_client -connect www.google.com:443 -tls1_3使用 curl
# 顯示詳細資訊
curl -v https://www.google.com
# 輸出:
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
# 測試特定 TLS 版本
curl --tlsv1.2 https://www.google.com
curl --tlsv1.3 https://www.google.com
# 顯示時間統計
curl -w "@curl-format.txt" -o /dev/null -s https://www.google.com
# curl-format.txt:
time_namelookup: %{time_namelookup}\n
time_connect: %{time_connect}\n
time_appconnect: %{time_appconnect}\n
time_redirect: %{time_redirect}\n
time_pretransfer: %{time_pretransfer}\n
time_starttransfer: %{time_starttransfer}\n
----------\n
time_total: %{time_total}\n🎓 面試常見問題
Q1:TLS 1.2 和 TLS 1.3 握手有什麼差異?
A:TLS 1.3 更快、更安全
主要差異:
1. 往返次數(RTT)
TLS 1.2:2-RTT
ClientHello →
← ServerHello + Certificate + ...
ClientKeyExchange + Finished →
← Finished
開始通訊(4 個訊息往返)
TLS 1.3:1-RTT
ClientHello + KeyShare →
← ServerHello + KeyShare + Certificate + Finished
Finished →
開始通訊(2 個訊息往返)
→ TLS 1.3 快一倍
2. 0-RTT(更快)
TLS 1.3 支援 0-RTT 恢復會話
→ 完全沒有額外延遲
→ 但有重放攻擊風險
3. 加密握手訊息
TLS 1.2:大部分握手訊息明文
TLS 1.3:握手訊息加密(除了 ClientHello/ServerHello)
→ 更好的隱私保護
4. 前向保密
TLS 1.2:可選(DHE/ECDHE)
TLS 1.3:強制(只支援 ECDHE)
→ 即使私鑰洩露,過去的通訊仍安全
5. 簡化加密套件
TLS 1.2:數十種加密套件(有些不安全)
TLS 1.3:只有 5 種安全套件
→ 移除所有不安全的選項
效能提升:
TLS 1.2:約 200ms
TLS 1.3:約 100ms
→ 快 100ms
結論:
✅ TLS 1.3 更快(1-RTT vs 2-RTT)
✅ TLS 1.3 更安全(強制前向保密)
✅ TLS 1.3 更簡單(更少選項)
✅ 建議使用 TLS 1.3Q2:握手過程中客戶端如何驗證憑證?
A:檢查五個方面
驗證流程:
1. 檢查憑證有效期
檢查:
- Not Before:憑證生效時間
- Not After:憑證過期時間
當前時間:2025-01-06
憑證有效期:2024-01-01 to 2026-01-01
→ 在有效期內 ✅
2. 檢查憑證網域名稱
檢查:
- Common Name (CN)
- Subject Alternative Name (SAN)
訪問:www.example.com
憑證 CN:www.example.com ✅
或
憑證 SAN:www.example.com, example.com ✅
3. 檢查憑證鏈(Chain of Trust)
網站憑證:www.example.com
↓ 由誰簽發?
中繼 CA:Let's Encrypt Authority X3
↓ 由誰簽發?
根 CA:ISRG Root X1
↓ 在瀏覽器信任清單中?
✅ 信任
4. 驗證數位簽章
CA 用私鑰簽署憑證
瀏覽器用 CA 公鑰驗證簽章
→ 簽章有效 ✅
→ 憑證未被篡改
5. 檢查憑證是否被撤銷
方法 1:CRL(Certificate Revocation List)
- 下載撤銷清單
- 檢查憑證序號是否在清單中
方法 2:OCSP(Online Certificate Status Protocol)
- 即時查詢憑證狀態
- 更快但需要額外請求
方法 3:OCSP Stapling
- 伺服器提供 OCSP 回應
- 不需要額外請求
全部通過:
✅ 憑證有效
🔒 顯示安全連線
任一失敗:
❌ 憑證無效
⚠️ 顯示警告Q3:什麼是前向保密(Perfect Forward Secrecy)?
A:即使私鑰洩露,過去的通訊仍然安全
傳統方式(RSA 金鑰交換):
1. 客戶端產生 Pre-Master Secret
2. 用伺服器公鑰(RSA)加密
3. 發送給伺服器
4. 伺服器用私鑰解密
問題:
駭客記錄所有加密流量(2020 年)
→ 未來取得伺服器私鑰(2025 年)
→ 解密 2020 年的流量
→ 看到所有通訊內容 ❌
前向保密(ECDHE):
1. 雙方各自產生「臨時」金鑰對
2. 交換公鑰
3. 計算共享密鑰
4. 用完就銷毀臨時私鑰
流程:
客戶端:
- 臨時私鑰:ecdhe_private_client
- 臨時公鑰:ecdhe_public_client
伺服器:
- 臨時私鑰:ecdhe_private_server
- 臨時公鑰:ecdhe_public_server
交換:
客戶端 → 伺服器:ecdhe_public_client
伺服器 → 客戶端:ecdhe_public_server
計算:
客戶端:ecdhe_private_client + ecdhe_public_server → 共享密鑰
伺服器:ecdhe_private_server + ecdhe_public_client → 共享密鑰
→ 相同的共享密鑰!
關鍵:
- 共享密鑰從未在網路上傳輸
- 臨時私鑰用完就銷毀
- 每次連線用不同的臨時金鑰
安全性:
駭客記錄所有流量(2020 年)
→ 未來取得伺服器長期私鑰(2025 年)
→ 仍然無法解密 2020 年的流量
→ 因為臨時私鑰已經銷毀了 ✅
TLS 支援:
TLS 1.2:可選(DHE/ECDHE 才支援)
TLS 1.3:強制(只支援 ECDHE)
檢查方法:
加密套件名稱包含 DHE 或 ECDHE
例:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384Q4:0-RTT 是什麼?有什麼風險?
A:立即恢復會話,但可能遭受重放攻擊
0-RTT(Zero Round Trip Time):
原理:
第一次連線:
ClientHello + KeyShare →
← ServerHello + ... + Session Ticket
Finished →
正常通訊
伺服器發送 Session Ticket(包含密鑰材料)
第二次連線(0-RTT):
ClientHello + Session Ticket + Early Data (HTTP Request) →
(不等握手完成,直接發送 HTTP 請求)
→ 完全沒有額外延遲!
優點:
✅ 最快(0 延遲)
✅ 用戶體驗最佳
風險:
1. 重放攻擊(Replay Attack)
駭客:攔截 0-RTT 請求
駭客:重新發送相同的請求
→ 如果是 POST /transfer(轉帳)
→ 可能重複執行 ❌
範例:
客戶端:0-RTT: POST /transfer?amount=1000
駭客:攔截並記錄
駭客:重新發送 100 次
→ 轉帳 100 次 ❌
2. 無前向保密
如果 Session Ticket 洩露
→ 可以解密 0-RTT 資料
防護措施:
1. 限制 0-RTT 用途
只允許冪等操作(GET)
禁止非冪等操作(POST, PUT, DELETE)
2. 伺服器防重放
- 記錄已使用的 Session Ticket
- 拒絕重複的 0-RTT 請求
- 限制 Session Ticket 有效期
3. 應用層檢查
- 加入 nonce(隨機數)
- 檢查請求時間戳
- 限制請求頻率
使用建議:
✅ 靜態資源(GET /style.css)
✅ 查詢操作(GET /search?q=keyword)
❌ 修改操作(POST /delete)
❌ 敏感操作(POST /login)
Nginx 設定:
ssl_early_data on;
應用層處理:
if request.headers.get('Early-Data') == '1':
# 這是 0-RTT 請求
if request.method != 'GET':
# 拒絕非 GET 請求
return 425 # Too Early
結論:
0-RTT 很快但有風險
只用於安全的冪等操作Q5:握手失敗常見原因有哪些?
A:憑證問題、協定不相容、網路問題
常見原因:
1. 憑證過期
錯誤:ERR_CERT_DATE_INVALID
原因:憑證超過有效期
解決:更新憑證
2. 憑證域名不符
錯誤:ERR_CERT_COMMON_NAME_INVALID
原因:憑證是給 www.example.com,但訪問 example.com
解決:使用 SAN 包含兩個域名,或重新導向
3. 自簽憑證
錯誤:ERR_CERT_AUTHORITY_INVALID
原因:憑證不是由可信任 CA 簽發
解決:使用真正的 CA 憑證(Let's Encrypt)
4. 缺少中繼憑證
錯誤:ERR_CERT_AUTHORITY_INVALID
原因:伺服器沒有提供完整的憑證鏈
解決:設定 fullchain.crt(包含中繼憑證)
5. TLS 版本不相容
錯誤:ERR_SSL_VERSION_OR_CIPHER_MISMATCH
原因:
- 伺服器只支援 TLS 1.0(已棄用)
- 客戶端只支援 TLS 1.2+
解決:升級伺服器支援 TLS 1.2/1.3
6. 加密套件不相容
錯誤:ERR_SSL_VERSION_OR_CIPHER_MISMATCH
原因:客戶端和伺服器沒有共同支援的加密套件
解決:
# Nginx
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
7. SNI 問題
錯誤:SSL_ERROR_UNRECOGNIZED_NAME_ALERT
原因:伺服器不支援 SNI
解決:升級伺服器軟體
8. OCSP 問題
錯誤:ERR_CERT_REVOKED
原因:憑證已被撤銷
解決:重新申請憑證
9. 時間不同步
錯誤:ERR_CERT_DATE_INVALID
原因:客戶端時間不正確
解決:同步系統時間
10. 防火牆阻擋
錯誤:ERR_CONNECTION_TIMED_OUT
原因:防火牆阻擋 443 port
解決:開放 443 port
除錯工具:
1. SSL Labs(https://www.ssllabs.com/ssltest/)
- 檢查伺服器 TLS 設定
- 評分 A+ 最好
2. OpenSSL
openssl s_client -connect example.com:443
3. curl -v
curl -v https://example.com
4. Chrome DevTools
- Network → 查看錯誤
- Security → 查看憑證資訊✅ 重點回顧
HTTPS 握手目的:
- 驗證伺服器身份
- 交換加密金鑰
- 協商加密演算法
TLS 1.2 握手(2-RTT):
ClientHello →
← ServerHello + Certificate + ...
ClientKeyExchange + Finished →
← FinishedTLS 1.3 握手(1-RTT):
ClientHello + KeyShare →
← ServerHello + KeyShare + Certificate + Finished
Finished →關鍵改進:
- TLS 1.3 更快(1-RTT vs 2-RTT)
- 0-RTT 支援(恢復會話)
- 握手訊息加密(更好隱私)
- 強制前向保密(ECDHE)
效能優化:
- Session Resumption(會話恢復)
- OCSP Stapling(減少延遲)
- TLS False Start(提前發送資料)
- 0-RTT(立即恢復會話)
憑證驗證:
- 檢查有效期
- 檢查域名
- 檢查憑證鏈
- 驗證簽章
- 檢查撤銷狀態
前向保密:
- 使用臨時金鑰(ECDHE)
- 每次連線不同金鑰
- 即使私鑰洩露,過去通訊仍安全
0-RTT:
- 優點:最快(0 延遲)
- 風險:重放攻擊
- 限制:只用於冪等操作(GET)
面試重點:
- ✅ TLS 1.2 vs 1.3 握手差異
- ✅ 憑證驗證流程
- ✅ 前向保密的原理和重要性
- ✅ 0-RTT 的優缺點
- ✅ 握手失敗常見原因
上一篇: 03-3. 數位憑證與 CA 下一篇: 04-1. WebSocket 基礎概念
最後更新:2025-01-06