本文描述了傳輸層安全性(TLS)中一種利用伺服器公鑰加密 ClientHello 訊息的機制。

這是一份網際網路標準軌文件,由網際網路工程任務組(IETF)社群共識產生,經公開審查並由網際網路工程指導組(IESG)核准發佈。

TLS 1.3 雖然加密了大部分握手過程,包括伺服器憑證,但仍有多種方式讓中間攻擊者得知連線的私密資訊。其中,ClientHello 訊息中未加密的伺服器名稱指示(SNI)擴展,會洩漏目標網域,是 TLS 1.3 中最敏感的未加密資訊。

本文規範了一種稱為加密 Client Hello(ECH)的新 TLS 擴展,允許客戶端將 ClientHello 加密傳送給 TLS 伺服器。此機制可保護 SNI 及其他可能敏感的欄位,如應用層協議協商(ALPN)清單。具有一致外部 TLS 配置與行為的共置伺服器形成匿名集合。使用此機制可揭露客戶端連接至特定服務提供者,但不會透露匿名集合中哪台伺服器終止連線。部署細節於第 8 節討論。

ECH 本身不足以完全保護伺服器身份,因為目標網域可能透過其他管道洩漏,例如明文 DNS 查詢或伺服器 IP 位址。但加密 DNS 機制(如 DNS over HTTPS、DNS over TLS/DTLS、DNS over QUIC)可協助客戶端隱藏 DNS 查詢,且許多 TLS 伺服器在同一 IP 位址上承載多個網域。私有來源也可能部署於共用提供者背後,如反向代理。在此環境下,SNI 仍是觀察者判斷伺服器身份的主要明確訊號。

ECH 支援 TLS 1.3、DTLS 1.3 及更新版本。

本文中關鍵字如 "MUST"、"SHOULD" 等,依 BCP 14 規範解釋,且僅在全大寫時適用。TLS 符號均來自 RFC8446 第 3 節。

ECH 協議設計有兩種拓撲:共享模式與分割模式。共享模式中,提供者為所有指向其的網域的原始伺服器,TLS 連線由提供者終止。分割模式中,提供者非私有網域的原始伺服器,DNS 記錄指向提供者,提供者伺服器將連線轉發回原始伺服器,由其終止 TLS 連線。此模式下,服務提供者無法存取除握手未加密部分外的明文內容。

本文後續稱 ECH 服務提供者為「面向客戶端伺服器」,TLS 終止者為「後端伺服器」。共享模式兩者為同一實體,分割模式則物理分離。

第 10 節詳述 ECH 威脅模型及其與客戶端、面向客戶端伺服器和後端伺服器的關係。

面向客戶端伺服器透過發佈 ECH 配置(包含加密公鑰及相關元資料)啟用 ECH。欲使用 ECH 的網域必須發佈此配置,使用與面向客戶端伺服器相關的金鑰。本文定義 ECH 配置格式,DNS 發佈細節交由 RFC9460 處理,RFC9848 說明如何在 SVCB 與 HTTPS 記錄中廣告 ECH 配置。其他傳遞方式亦可行,例如客戶端預先配置 ECH 設定。

當客戶端欲與後端伺服器建立 TLS 連線時,會構造一個私密的 ClientHello,稱為 ClientHelloInner,並構造一個公開的 ClientHello,稱為 ClientHelloOuter。ClientHelloOuter 包含對敏感擴展的無害值及一個 "encrypted_client_hello" 擴展,攜帶加密的 ClientHelloInner。客戶端將 ClientHelloOuter 發送給伺服器。

伺服器採取以下行動之一:

若不支援 ECH 或無法解密擴展,則以 ClientHelloOuter 完成握手,稱為拒絕 ECH。

若成功解密擴展,則將 ClientHelloInner 轉發給後端伺服器,由其完成握手,稱為接受 ECH。

客戶端收到伺服器回應後,判斷是否接受 ECH,並依此繼續握手。拒絕 ECH 時,該連線無法用於應用資料,客戶端可利用此拒絕訊號以最新配置重試。

ECH 主要目標是確保匿名集合中伺服器的連線彼此無法區分,且不影響 TLS 1.3 既有安全性。第 10.1 節詳述 ECH 的安全與隱私目標。

ECH 使用混合公鑰加密(HPKE)進行公鑰加密。ECH 配置由 ECHConfig 結構定義,包含版本、長度及依版本不同的內容(ECHConfigContents 結構)。

ECHConfigContents 包含 HPKE 公鑰配置(HpkeKeyConfig)、後端伺服器的最長名稱(用於計算填充)、面向客戶端伺服器的 DNS 名稱(用於修正錯誤配置)及 ECH 配置擴展列表。

HpkeKeyConfig 包含一字節的金鑰配置識別碼、HPKE KEM 識別碼、公鑰及可用的 KDF/AEAD 算法列表。

面向客戶端伺服器向客戶端廣告一組 ECH 配置(ECHConfigList),依偏好順序排列,支援多版本及多組參數。

伺服器應包含目前及先前仍可能使用的配置,以因應客戶端快取。

第 7.1 節描述 ClientHello 試解密流程,可能影響性能,建議伺服器為每個配置分配不同的 config_id。

ECH 配置擴展用於擴充功能,格式與 TLS 擴展類似,但可標記為強制性。客戶端必須解析並忽略不支援的強制擴展。

未來影響 ClientHelloOuter 的資訊應以 ECH 配置擴展形式提供,因為 ClientHelloOuter 僅用於支援 ECH,且是加密 ClientHelloInner 的封套及鑑權用。

客戶端提供 ECH 時,ClientHelloOuter 與 ClientHelloInner 均須包含 "encrypted_client_hello" 擴展,外層擴展攜帶加密資料,內層擴展為空。

伺服器回應時,若使用 ClientHelloOuter,可能在 EncryptedExtensions 中包含 "encrypted_client_hello" 擴展,攜帶重試配置。

若客戶端以內層擴展發送且伺服器回應 HelloRetryRequest,必須包含 "encrypted_client_hello" 擴展,攜帶確認值。

本文定義 "ech_required" 警示,客戶端在提供 ECH 擴展但未被接受時必須發送。

加密前,客戶端會將 ClientHelloInner 填充並(可選)壓縮成 EncodedClientHelloInner 結構。

客戶端可用 "ech_outer_extensions" 擴展替換 ClientHelloInner 中與 ClientHelloOuter 重複的擴展,以減少大小。

填充機制基於內部擴展長度,確保外部封包大小不洩漏敏感資訊。

面向客戶端伺服器解密時,會驗證填充並重建 ClientHelloInner,若有異常則終止連線。

為防止攻擊者修改 ClientHelloOuter 而不改變加密內容,ECH 使用 HPKE 的關聯資料(ClientHelloOuterAAD)對 ClientHelloOuter 進行鑑權。

客戶端實作 ECH 擴展有兩種行為:提供真實 ECH 擴展或發送 GREASE 偽造擴展,後者用於與不支援 ECH 的伺服器互通。

客戶端選擇合適的 ECHConfig,並依規則構造 ClientHelloInner,禁止協商 TLS 1.2 以下版本及相關會話恢復。

ClientHelloOuter 由 ClientHelloInner 加密產生,並包含必要欄位與隨機數。

客戶端在 ClientHelloOuter 不得廣告 PSK 身份,但可在 ClientHelloInner 中包含 PSK,並在外層使用 GREASE 擴展以避免協議違規。

填充長度計算考慮 ALPN 與 SNI 長度,並以 32 位元倍數對齊。

伺服器可接受或拒絕 ECH,接受時使用 ClientHelloInner,拒絕時使用 ClientHelloOuter。

客戶端根據伺服器回應判斷 ECH 是否被接受,並依此繼續握手或重試。

拒絕 ECH 時,客戶端需以公用名稱驗證憑證,且不應將連線視為成功,僅用於觸發重試。

客戶端應驗證 ECHConfig 的 public_name 是否為有效主機名稱,避免誤判為 IP 位址。

客戶端可利用拒絕 ECH 時獲得的配置資訊優化未來連線,但必須視為新連線處理。

GREASE ECH 機制讓不支援 ECH 的伺服器看似支援,減少 ECH 連線的異常感。

伺服器角色分為面向客戶端伺服器與後端伺服器,兩者處理 ECHClientHello 類型不同。

分割模式下,面向客戶端伺服器不應接收內層 ClientHello,後端伺服器不應接收外層 ClientHello,違者終止連線。

共享模式下,伺服器先解密外層 ClientHello,再使用內層內容,直接接收內層 ClientHello 亦終止連線。