HTTPS 與 TLS 實際運作原理:實用指南
你可能已經看過瀏覽器中的鎖頭圖示,並知道它代表「安全」。但當你造訪一個 HTTPS 網站時,實際發生了什麼事?瀏覽器如何知道它正在與真正的伺服器通訊,而不是冒充者?為什麼 TLS 有時會拖慢速度?本指南將以實用角度拆解 HTTPS 與 TLS,讓你信心十足地設定、除錯並保護你的 Web 應用程式。
HTTPS 到底是什麼
HTTPS 簡單來說就是將 HTTP 疊加在 TLS(Transport Layer Security,傳輸層安全性)之上。TLS 提供三項保證:
- 機密性:資料經過加密,竊聽者無法讀取。
- 完整性:資料在傳輸過程中若被竄改,將會被偵測到。
- 認證:伺服器使用憑證來證明其身分。
沒有 TLS 的 HTTP 會以明文傳送所有內容:密碼、Cookie 和個人資料都會暴露在網路路徑上的任何人眼中。HTTPS 解決了這個問題。
用白話解釋 TLS 握手
在任何加密資料流動之前,用戶端與伺服器會先進行握手,以協商加密金鑰並驗證身分。以下是典型 TLS 1.3 握手(現代標準)的過程:
- Client Hello:瀏覽器傳送支援的加密套件清單、TLS 版本以及一個隨機值。
- Server Hello:伺服器選擇一個加密套件,傳送自己的隨機值,並提供其憑證鏈。
- 金鑰交換:雙方使用金鑰交換演算法(如 ECDHE)來推導共享密鑰,而無需直接傳輸該密鑰。
- 憑證驗證:用戶端根據受信任的根 CA 檢查伺服器的憑證、驗證網域名稱並檢查到期時間。
- 完成:雙方傳送 MAC 以確認握手完整性,然後開始傳送加密的應用程式資料。
TLS 1.3 將此過程減少到單次往返(1-RTT),甚至支援重複造訪者的 0-RTT 恢復,與 TLS 1.2 相比大幅降低延遲。
憑證:信任的錨點
憑證將公開金鑰綁定到網域名稱,並由憑證授權單位(CA)簽署。瀏覽器和作業系統內建受信任的根 CA 儲存庫。當伺服器出示其憑證時,用戶端會驗證憑證鏈直至受信任的根。
常見的憑證類型:
- DV(網域驗證):證明對網域的控制權;簽發快速且通常免費(例如 Let's Encrypt)。
- OV(組織驗證):包含經過驗證的組織詳細資訊;簽發時間較長。
- EV(擴展驗證):最高驗證等級;歷史上會顯示綠色網址列,但現代瀏覽器已不再強調此點。
憑證會過期,因此自動化至關重要。與反向代理整合的 Certbot 或 ACME 用戶端等工具會自動處理續約。
在伺服器上設定 HTTPS
以下是一個啟用 HTTPS 並採用現代 TLS 設定的最小 Nginx 配置:
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';
ssl_prefer_server_ciphers off;
# HSTS (測試後再啟用)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
location / {
proxy_pass http://localhost:3000;
}
}
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
重點:僅使用 TLS 1.2 和 1.3,偏好 ECDHE 加密套件以實現前向保密,並將 HTTP 重新導向至 HTTPS。HSTS 會告訴瀏覽器永遠對你的網域使用 HTTPS,但在啟用長 max-age 之前請先仔細測試。
常見陷阱與避免方法
- 混合內容:在 HTTPS 頁面載入 HTTP 資源會破壞鎖頭圖示。使用相對 URL 或確保所有資源都使用 HTTPS。
- 憑證過期:自動化續約並監控到期時間。過期的憑證會立即引發瀏覽器警告。
- 弱協定:停用 TLS 1.0 和 1.1;它們已被棄用且存在漏洞。
- 不完整的憑證鏈:伺服器必須傳送中繼憑證;否則某些用戶端會失敗。使用 SSL Labs 等工具進行測試。
- 未預載 HSTS:為獲得最大保護,在確保所有子網域都支援 HTTPS 後,將你的網域提交到 HSTS 預載清單。
TLS 1.2 與 TLS 1.3:有何改變
| 功能 | TLS 1.2 | TLS 1.3 |
|---|---|---|
| 握手往返次數 | 2-RTT | 1-RTT(恢復時 0-RTT) |
| 金鑰交換 | RSA 或 ECDHE | 僅 ECDHE(強制前向保密) |
| 加密套件 | 多種,包括弱加密套件 | 精簡集合,全部為 AEAD |
| 0-RTT 資料 | 不支援 | 支援(有重播風險) |
TLS 1.3 更快且更簡單,移除了舊式演算法。大多數現代用戶端都支援它,但請保留 TLS 1.2 以相容於較舊的裝置。
除錯 TLS 問題
當 HTTPS 失敗時,請檢查以下事項:
- 使用
openssl s_client -connect example.com:443 -servername example.com檢查憑證鏈和握手。 - 執行
curl -vI https://example.com查看協商的 TLS 版本和加密套件。 - 檢查伺服器日誌中的握手錯誤;Nginx 會將 SSL 錯誤記錄到錯誤日誌。
- 使用線上 SSL 測試工具取得全面評分和建議。
如果你經常處理 Nginx 日誌,Nginx 日誌分析器 可以幫助你快速找出 TLS 握手失敗和其他問題。
常見問題
HTTPS 和 TLS 有什麼區別?
HTTPS 是運行在 TLS 之上的 HTTP。TLS 是提供加密、完整性和認證的密碼學協定。HTTPS 是使用 TLS 的 HTTP 安全版本。
內部服務需要憑證嗎?
是的,對於生產環境的內部服務,請使用來自你自己 CA 或公共 CA 的憑證。自簽憑證會導致信任問題;考慮使用私有 PKI 或像 mkcert 這樣的開發工具。
憑證應該多久更新一次?
現代最佳實踐是使用 90 天憑證並自動續約,如 Let's Encrypt 所提供的。較短的生命週期可降低金鑰外洩時的風險。
準備好保護你的網站了嗎?首先使用 SSL 檢查工具測試你目前的 TLS 設定,然後套用上述 Nginx 設定。如需深入了解 Web 安全,請探索我們關於 OWASP Top 10 和 XSS 防範的其他指南。