具代表性的面試主題

如何用 RFC 8879 壓縮 TLS 憑證鏈而不引入握手 DoS?

後端困難
Offer.cc 編輯團隊發佈 更新

題幹

你的 TLS 服務憑證鏈很大,影響 QUIC 和行動網路握手。請依據 RFC 8879 設計憑證壓縮協商、解壓限制、快取、回退與監控方案,並說明安全邊界。

題目與背景

TLS 憑證鏈會佔用握手位元組,較大的鏈可能增加分片、丟包和 QUIC 初始往返成本。RFC 8879 定義 compress_certificate 擴充,讓端點協商壓縮演算法並傳送壓縮後的 Certificate 訊息。請設計可灰度部署的伺服器方案,重點處理解壓資源上限、演算法不匹配和相容回退。

面試官考察什麼

重點是區分壓縮憑證訊息與壓縮應用資料,理解擴充協商方向、演算法註冊、解壓後長度校驗和憑證鏈語意不變。優秀答案會討論 Brotli、Zstandard 等演算法的 CPU/頻寬權衡,以及惡意壓縮資料造成的記憶體和 CPU 消耗。

先問清楚的澄清問題

協定與用戶端範圍

確認 TLS 1.3、DTLS 或 QUIC 的比例,用戶端是否能升級,以及中間盒是否會丟棄未知擴充。TLS 1.2 不能直接套用 TLS 1.3 的壓縮擴充路徑。

憑證鏈形態

確認鏈長度、重複憑證比例、是否有後量子或企業擴充,以及鏈是否按租戶變化。鏈的穩定性決定壓縮快取收益和預生成策略。

風險預算

確認目標是降低握手位元組、減少初始分片,還是降低行動端耗電。還要設定解壓 CPU、記憶體和最大未壓縮訊息大小。

30 秒回答框架

「用戶端在 ClientHello 中宣告支援的演算法,伺服器只選擇交集並傳送壓縮 Certificate 訊息;用戶端解壓後按普通憑證鏈驗證,不能跳過簽章、名稱和有效期檢查。限制壓縮輸入、解壓後長度和 CPU 時間,避免壓縮炸彈。快取按憑證鏈和演算法版本鍵控,失敗或不支援時回退到普通 Certificate。灰度觀察握手失敗、回退率、解壓耗時和初始封包大小,演算法升級必須可回滾。」

深入解答步驟

第一步:定義協商流程

用戶端在擴充中列出可接受的演算法編號,伺服器選擇一個共同演算法;沒有交集就傳送普通 Certificate。演算法編號和語意以 IANA 註冊為準,不自行重用未知編號。

第二步:生成與快取壓縮鏈

把完整憑證鏈按演算法壓縮並快取,快取鍵包含鏈內容摘要、演算法編號和實作版本。憑證輪換、鏈順序變化或演算法升級時失效,不能把舊鏈壓縮結果套到新鏈。

第三步:設定解壓防線

在讀取壓縮輸入、配置輸出緩衝和解析憑證前設定最大壓縮長度、最大解壓長度、最大憑證數量及 CPU/時間預算。超過限制立即終止握手;伺服器也不能因用戶端宣告演算法就無限信任其解壓實作。

第四步:保持憑證驗證不變

解壓只是傳輸表示變化。用戶端仍需驗證鏈簽章、主機名、有效期、金鑰用途、信任錨和 TLS 繫結,解析失敗或鏈不一致必須失敗,不能靜默使用快取的舊憑證。

第五步:處理回退與中間盒

區分用戶端不支援、演算法無交集、壓縮訊息損壞和解壓超限。前兩者可回退普通 Certificate;損壞或超限應記錄並失敗,避免攻擊者透過反覆失敗迫使伺服器降級。灰度按地區、用戶端版本和協定分層。

第六步:權衡 CPU 與頻寬

預壓縮穩定鏈可以把 CPU 成本移到發布流程;動態租戶鏈則要設定快取命中和過期策略。選擇演算法時比較壓縮率、解壓速度、實作可用性和用戶端支援,不以「壓縮率最高」單一指標決策。

第七步:觀測和演練

記錄演算法協商、普通回退、解壓拒絕、握手耗時、初始封包大小和 CPU,不記錄憑證私鑰。演練憑證輪換、快取失效、惡意超大輸出、演算法下線和全量回退,驗證不支援用戶端仍可連線。

高品質示例回答

我會讓用戶端在 ClientHello 宣告演算法,伺服器僅選擇交集並傳送壓縮 Certificate;無交集時發普通鏈。壓縮快取按鏈摘要、演算法和實作版本隔離,輪換即失效。用戶端先限制輸入和解壓後大小、憑證數及 CPU,再按原有 X.509 和 TLS 規則驗證。損壞或超限直接失敗,不把異常降級;透過灰度監控回退率、解壓成本和 QUIC 初始封包收益,演算法可快速關閉。

常見錯誤

  • 錯誤: 認為壓縮後可以減少憑證驗證。→ 原因: 壓縮只改變傳輸表示。→ 改進: 解壓後執行完整鏈驗證。
  • 錯誤: 只限制壓縮輸入大小。→ 原因: 小輸入也可能展開成巨大輸出。→ 改進: 同時限制輸出長度、憑證數和 CPU。
  • 錯誤: 所有失敗都靜默回退普通鏈。→ 原因: 把相容問題與惡意損壞混為一談。→ 改進: 僅對不支援或無交集回退,損壞與超限記錄並失敗。
  • 錯誤: 快取只按網域鍵控。→ 原因: 同網域可能因輪換、演算法和租戶產生不同鏈。→ 改進: 納入鏈摘要、演算法和版本。

追問與回答

追問 1:憑證壓縮能否用於 TLS 1.2?

RFC 8879 的擴充面向 TLS 1.3、DTLS 1.3 等內容;不能把 TLS 1.3 的協商欄位直接套到 TLS 1.2。具體協定版本必須按實作和規範驗證。

追問 2:為什麼要限制解壓後的長度?

壓縮比可能很高,攻擊者可用小請求誘導巨大記憶體配置或 CPU 消耗。輸出上限是防壓縮炸彈和資源耗盡的必要邊界。

追問 3:演算法無交集時伺服器應該做什麼?

傳送普通 Certificate,保持標準握手;同時記錄用戶端能力分布,評估是否值得繼續支援壓縮。不能自行選擇用戶端未宣告的演算法。

追問 4:QUIC 為什麼更關注憑證壓縮?

QUIC 初始握手對封包數和路徑丟包更敏感,減少憑證位元組有機會讓伺服器初始訊息更緊湊。但收益必須與解壓 CPU、用戶端支援和鏈大小共同評估。

公開來源

同類題目