憑證和 challenge 運作原理
整理憑證簽發流程、challenge 種類、client 判斷憑證可信的依據,以及憑證鏈與 CN / SAN / SNI 的差異。
問題
- 憑證是怎麼簽出來的
- Client 怎麼判斷這個憑證是否可信
憑證的簽發流程
- 生成 CSR 和 private key
- 使用 OpenSSL 或其他工具生成一組 key pair
- 生成 CSR,內容包含
- public key
- 申請的域名 Common Name (CN)(或 SAN)
- 公司名稱與部門
- 申請者的國家與地區
- 用 private key 簽出來的 Hash 簽名,用於證明 CSR 的合法性與完整性
- 將 CSR 提交給 CA,CA 驗證 CSR 的合法性與可信性 (challenge)
- Domain Validation:Email / DNS records / HTTP file
- Organization Validation
- Extended Validation:最嚴格,適用於高安全性需求的網站
- 簽發憑證
- CA 拿自己的 private key 簽 CSR 中的數據,生成憑證
憑證後續通訊的作用
TLS/SSL Handshake 階段
- server 發送憑證(包含 public key / CA 簽名等資訊)給 client
- client 瀏覽器驗證:是否由 CA 簽發 / 是否過期 / 域名是否相符等
- 交換 DHE public key:
- server DHE public key + openssl private key 簽章
- client 拿 openssl public key 解出 server DHE public key
- client 生成 DHE key pair,並把 DHE public key 給 server
- client/server 用雙方的 DHE public key 計算出對稱式共享密鑰,結果一致,並用於加密通訊
Challenge 的種類和原理
| Challenge 類型 | 驗證方式 | 權限要求 | 安全機制 |
|---|---|---|---|
| HTTP-01 | 在特定路徑放置檔案 | Web Server 控制權 | - Challenge 值動態生成 - CA 直接訪問驗證 |
| DNS-01 | 新增 TXT record | DNS 設定權限 | - Challenge 值動態生成 - 全球可驗證 |
| TLS-ALPN-01 | 配置臨時 TLS 憑證 | DNS Server 控制權 | - TLS 加密通訊 - 臨時憑證單次有效 |
| 回覆驗證郵件 | 域名管理郵箱存取權 | - 使用註冊時設定的管理郵箱 - 需要郵箱存取權限 |
共同特點:
- 都需要證明對域名或伺服器的控制權
- 都使用動態生成的 challenge 值確保安全性
- 都有特定的驗證機制防止偽造
原回答
- HTTP-01 Challenge
- 驗證:CA 要求申請者在 server 某特定路徑放置指定文件,文件內包含 challenge 值
- 可信的理由
- 只有具有 server 控制權的人才有辦法放置驗證文件
- Challenge 值動態生成,唯一對應該次驗證、防止復用或偽造
- CA 親自訪問並驗證內容、排除中間干擾
- DNS-01 Challenge
- 驗證:CA 要求申請者在域名的 DNS 設定中新增一條 TXT record,內容為 challenge 值
- 可信的理由
- 只有擁有 DNS 設定權限的人才有辦法修改 TXT record
- DNS record 全球皆可驗證
- Challenge 值動態生成,不可重複使用
- TLS-ALPN-01 Challenge
- 驗證:CA 要求申請者在 server 臨時配置一個 TLS 憑證(ACME 協議),內容包含 Challenge 值
- 可信的理由
- 只有擁有 DNS name server 控制權的人才能設定 TLS 憑證
- CA 與 server 之間的驗證採 TLS 加密,防止中間人攻擊
- 臨時憑證只適用於該次驗證,驗證完後立即失效
- Email Challenge
- 驗證:CA 發送 challenge 驗證郵件到域名中的郵箱,申請者須根據郵件內容,將 challenge 回傳給 CA
- 可信的理由
- 能操作該郵件的人通常具有域名的管理權
- 這些郵箱通常是域名註冊時預設的管理者郵箱
Client 判斷憑證可信的基礎
- 憑證是否由可信的 CA 簽發
- 檢查憑證的發行者欄位
- 如果憑證的簽名鏈(憑證鏈)可以追溯到一個可信的 root CA,則憑證可信
- 憑證是否與 domain name 匹配
- 檢查憑證的 Common Name 或 Subject Alternative Name,有沒有和請求中的域名匹配
- 憑證是否在效期內
- 憑證是否已被吊銷
- 使用 Certificate Revocation List (CRL) 查詢憑證是否被列入黑名單
- 使用 Online Certificate Status Protocol (OCSP) 檢查該憑證的狀態
- 憑證簽名是否有效
- Client 可以使用 CA 的 public key 來驗證 server 憑證的數位簽名
- server 是否正確提供完整的憑證鏈
- 加密協議是否安全
- Client 在 TLS 交握時,會檢查 server 支援的加密演算法和協議版本
憑證鏈的概念
- Server/Leaf Certificate
- 被 Intermediate Certificate 簽出來的憑證
- Intermediate Certificate
- 由 Root CA 簽出來的憑證
- 通常不只一層,會有多個級別
- 用於分散風險,減少 Root CA 的直接使用
- Root Certificate
- 由 CA 直接簽出來的憑證
- 被 Client 直接信任
CN / SAN / SNI
- SAN 是 SSL/TLS 憑證 (X.509) 中的一個欄位,用於指定憑證所保護的多個域名
- CN 是舊版憑證中的欄位,指定憑證所保護的單一域名
- SNI 是 TLS 協定中的一個功能,讓 proxy/server 可以根據 request 發送的對象 (i.e., host header) 來決定回傳哪張憑證給 client
為什麼要有 SNI
- 問題來源:
- 早期 TLS/SSL 協議中,一個 IP address 只能對應到一張憑證
- 當時 TLS 交握時,Client 不會跟 server 說他希望連接的域名是誰,因此 server 只能根據 IP 選擇一個預設的憑證回傳
- 導致的結果:
- 當 server 身上有多個域名時 (i.e., virtual hosting),這些域名需要不同的憑證,但在沒有 SNI 的情境下,server 只能回傳預設的憑證
- 當時的解法:
- 為每個域名配置獨立的 IP,但這樣增加了 IP 的需求(IP 是有限的)
有了 SNI 之後的改進
- Client 在 TLS 交握的 “ClientHello” 階段就會一併送出他要訪問的域名
- Server 根據 SNI 中的域名,回傳正確的憑證給 Client
為啥會有 SNI 跟 SAN 並行的情況
- 先有 SAN 才有 SNI
- SNI 主要是為了解決 virtual hosting 上,沒有使用 SAN 的情境