HTTPS 與 TLS 的真正運作方式:握手與憑證
為什麼 HTTPS 很重要(以及為什麼它常被誤解)
你可能在瀏覽器中看過鎖頭圖示,並認為該網站是「安全的」。但這到底意味著什麼?HTTPS 不僅僅是加密;它還涉及身分驗證、完整性和信任。許多開發者將 TLS 視為黑盒子——配置一次後就忘記它。這會導致配置錯誤、憑證過期和易受攻擊的加密套件。
在本文中,我們將分解 HTTPS 和 TLS 的實際運作方式,從握手到憑證驗證,並展示如何正確設置。沒有廢話,只有你今天就可以應用的實用知識。
TLS 握手:第一個位元組之前發生的事
當客戶端(瀏覽器)透過 HTTPS 連接到伺服器時,它們會執行 TLS 握手。這建立了一個安全通道。以下是簡化版本(TLS 1.3):
- Client Hello: 客戶端發送支援的加密套件、一個隨機值和一個金鑰共享(用於金鑰交換)。
- Server Hello: 伺服器選擇一個加密套件,發送自己的隨機值和金鑰共享,並出示其憑證鏈。
- 身分驗證: 客戶端根據受信任的 CA 驗證伺服器的憑證,並檢查主機名稱。
- 金鑰衍生: 雙方使用 ECDHE(橢圓曲線迪菲-赫爾曼臨時金鑰交換)計算共享密鑰。
- 完成: 雙方發送加密的「Finished」訊息以確認握手。
在此之後,應用程式資料會使用對稱金鑰加密。TLS 1.3 將往返次數減少到一次,從而改善延遲。
金鑰交換:ECDHE 與 RSA
較舊的 TLS 版本使用 RSA 金鑰交換,缺乏前向保密性。如果伺服器的私鑰被洩露,過去的流量可以被解密。現代設置使用 ECDHE,它提供前向保密性——每個會話都有唯一的金鑰。
# 範例:檢查支援的金鑰交換演算法
openssl s_client -connect example.com:443 -cipher 'ECDHE'
憑證:信任的錨點
憑證將公鑰綁定到身分(網域名稱)。它由客戶端信任的憑證授權單位(CA)簽署。瀏覽器內建了受信任的根 CA 存儲庫。
當你訪問一個網站時,伺服器會發送一個鏈:葉憑證(用於你的網域)→ 中間 CA → 根 CA。客戶端驗證每個簽名,直到受信任的根。
憑證類型
- 網域驗證(DV): 僅證明對網域的控制。快速且免費(例如 Let's Encrypt)。
- 組織驗證(OV): 包括經過驗證的組織詳細資訊。
- 擴展驗證(EV): 更嚴格的審查;瀏覽器不再顯示綠色網址列,但一些企業仍在使用它們。
憑證驗證步驟
瀏覽器檢查:
- 簽名鏈指向受信任的根。
- 憑證在其有效期內。
- 主機名稱匹配(主體別名)。
- 憑證未被撤銷(透過 OCSP 或 CRL)。
如果任何檢查失敗,你會收到警告。在生產環境中絕不要繞過這些警告。
在伺服器上配置 HTTPS
讓我們看一個典型的 Nginx 配置,使用現代 TLS 設置啟用 HTTPS。
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers off;
# HSTS(謹慎使用)
add_header Strict-Transport-Security "max-age=63072000" always;
}
注意事項:
- 僅使用 TLS 1.2 和 1.3;停用較舊的版本。
- 優先使用 ECDHE 加密套件以實現前向保密性。
- 啟用 HTTP/2 以提升效能。
- HSTS 強制瀏覽器使用 HTTPS;僅在測試後啟用。
使用 Let's Encrypt 取得憑證
Let's Encrypt 提供免費的 DV 憑證。使用 Certbot 自動化簽發和續期:
sudo certbot --nginx -d example.com -d www.example.com
Certbot 會修改你的 Nginx 配置並設置一個 cron 作業來續期。始終使用 --dry-run 測試續期。
常見陷阱及如何避免
- 憑證過期: 設置監控和自動續期。
- 不完整的鏈: 包含中間憑證(fullchain.pem)。
- 弱加密套件: 停用 RC4、DES 和出口級加密套件。
- 混合內容: 確保所有資源(圖片、腳本)透過 HTTPS 載入。
- 沒有 HSTS: 沒有 HSTS,使用者可能被降級到 HTTP。
測試你的 HTTPS 配置
使用 SSL Labs 等線上工具或命令列工具來驗證你的設置。
# 檢查憑證詳細資訊
openssl s_client -connect example.com:443 -servername example.com | openssl x509 -noout -text
# 測試 TLS 1.3 支援
openssl s_client -connect example.com:443 -tls1_3
尋找:
- 有效的憑證鏈。
- 沒有弱協議(SSLv3、TLS 1.0、TLS 1.1)。
- 啟用了前向保密性。
- 存在 HSTS 標頭。
常見問題
TLS 和 SSL 有什麼區別?
SSL 是 TLS 的前身。TLS 1.0 本質上是 SSL 3.1。今天,「SSL」常被口語化使用,但你應該始終使用 TLS 1.2 或 1.3。
我需要付費憑證才能使用 HTTPS 嗎?
不需要。來自 Let's Encrypt 的免費 DV 憑證受到所有主要瀏覽器的信任,並提供與付費憑證相同的加密。付費憑證提供保證和支援,但加密是相同的。
HTTPS 如何影響效能?
TLS 由於握手而增加延遲,但 TLS 1.3 將其減少到一次往返。透過會話恢復和 HTTP/2,開銷最小。在現代 CPU 上,加密/解密成本很低。
準備好檢查你的伺服器 TLS 配置了嗎?使用我們的 Nginx 日誌分析器 來發現異常流量模式,並確保你的 HTTPS 設置按預期運作。