為什麼要 TLS,只加密不夠嗎

假設你和銀行之間有一個加密通道——但你怎麼知道你連的是真正的銀行,不是一個攻擊者偽裝成銀行,然後用自己的 key 加密?

TLS 解決三件事:

  1. 加密(Confidentiality):通訊內容不被第三方看到
  2. 完整性(Integrity):內容不被篡改(MAC)
  3. 認證(Authentication):確認 server 的身份(certificate)

TLS 握手(簡化版 TLS 1.2)

Client                          Server
  │─── Client Hello ──────────→ │   支援的 TLS 版本、cipher suites、random number
  │                              │
  │ ←── Server Hello ──────────  │   選定的 cipher suite、random number
  │ ←── Certificate ───────────  │   server 的公鑰憑證
  │ ←── Server Hello Done ──────  │
  │                              │
  │ 驗證憑證 (Certificate Chain)  │
  │                              │
  │─── Client Key Exchange ───→ │   用 server 公鑰加密的 pre-master secret
  │─── Change Cipher Spec ────→ │   接下來用協商的 session key 加密
  │─── Finished ──────────────→ │
  │                              │
  │ ←── Change Cipher Spec ──── │
  │ ←── Finished ───────────── │
  │                              │
  │════ 加密的應用資料 ══════════ │

TLS 1.3 把握手壓縮到 1 RTT(從 TLS 1.2 的 2 RTT),大幅降低延遲。


Certificate Chain(憑證鏈)

你的瀏覽器為什麼信任 api.example.com 的憑證?

Root CA(瀏覽器內建信任)
  └── Intermediate CA
        └── api.example.com Certificate

瀏覽器信任一批 Root CA(Let’s Encrypt, DigiCert, Comodo 等)。Root CA 簽發給 Intermediate CA,Intermediate CA 再簽發給你的域名憑證。你的瀏覽器驗證整個鏈都有效,才信任你的 server。

常見的 Certificate Error

  • ERR_CERT_AUTHORITY_INVALID:憑證不是受信任的 CA 簽發的(自簽憑證、或 intermediate CA 沒有正確包含在回應裡)
  • ERR_CERT_DATE_INVALID:憑證過期(Let’s Encrypt 憑證 90 天,要自動續期)
  • ERR_CERT_COMMON_NAME_INVALID:域名不符(憑證是 example.com 但你連到 api.example.com,需要 wildcard *.example.com 或 SAN)

自簽 vs CA 簽發

CA 簽發(Let’s Encrypt 免費):瀏覽器信任,生產環境用。

自簽憑證:自己當 CA 簽自己的憑證,瀏覽器不信任(顯示警告)。適合:

  • 本機開發環境(mkcert 讓本機 CA 被信任)
  • 服務間的 mTLS(雙方都信任同一個內部 CA)

Cipher Suite

TLS 握手時雙方協商一組加密算法:

TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
 └─────────────────────────────────────
  Key Exchange: ECDHE(提供 Forward Secrecy)
  Authentication: RSA
  Bulk Encryption: AES-256-GCM
  MAC: SHA-384

Forward Secrecy:ECDHE / DHE key exchange 每個 session 生成不同的 session key,即使伺服器私鑰洩漏,過去的通訊也無法被解密——因為 session key 沒有存下來。

TLS 1.3 移除了所有不支援 Forward Secrecy 的 cipher suite,讓 HTTPS 更安全。