後量子金鑰交換為 TLS ClientHello 增加新欄位。了解 ML-KEM 和 ML-DSA 如何重塑 JA3/JA4 指紋,以及這對偵測系統意味著什麼。
2026 年,後量子密碼學不再只是研究課題,而是開始出現在生產環境的 TLS 握手中。Cloudflare 最近撰文主張經典簽章演算法不能單純等待更好的後量子替代方案,APNIC 也一直在追蹤後量子密碼在網路維運層面的實際落地情況。這兩篇文章談的都是部署問題,而非指紋識別——但它們描述的機制所改變的,正是 JA3/JA4 指紋識別一直在讀取的那個 ClientHello。本文要談的正是這個副作用:後量子金鑰交換與簽章演算法,究竟對你的 TLS 指紋做了什麼。
核心重點
- 後量子金鑰交換為 ClientHello 增加了一個新的支援群組,而非新協定。 像
X25519MLKEM768這樣的混合機制,位於 JA3/JA4 早已在雜湊的同一批supported_groups和key_share擴充功能中。 - 金鑰共享的資料量大得多。 經典的 X25519 金鑰共享只有 32 位元組;混合 ML-KEM-768 的金鑰共享則遠超 1000 位元組——有時足以讓 ClientHello 跨越 UDP 或分段 TCP 的邊界。
- ML-DSA 影響的是另一個擴充功能
signature_algorithms,用於握手簽章而非金鑰交換——是同一則訊息中一次獨立而互補的變化。 - 各瀏覽器與版本的支援程度並不一致,因此客戶端是否提供 PQC 支援群組、以及它出現在什麼位置,構成了一個全新且目前高熵的指紋訊號。
- JA4 已經能正確處理這項變化。 由於它在雜湊前會依數值排序擴充功能和密碼套件,客戶端開啟或關閉 PQC 支援只會改變參與雜湊的排序值集合——不會像順序敏感的 JA3 那樣破壞格式。
ClientHello 裡到底新增了什麼
TLS 指紋識別之所以成立,是因為 ClientHello——密碼套件、擴充功能、支援群組、金鑰共享——由 TLS 函式庫決定,而非由使用者決定。後量子金鑰交換並沒有增加新的訊息類型或新的往返,它改變的是同一個 ClientHello 中既有兩個欄位的內容:
supported_groups新增了一個或多個用於混合金鑰交換的命名群組,最引人注目的是X25519MLKEM768——它結合了經典的 X25519 橢圓曲線 Diffie-Hellman 與基於格的金鑰封裝機制 ML-KEM-768(NIST 已將其標準化為 FIPS 203)。IETF 的 TLS 混合 ML-KEM 金鑰交換草案精確規定了這在 TLS 1.3 中如何協商。key_share攜帶客戶端願意主動傳送的各個群組所對應的實際金鑰材料。這正是 PQC 留下最明顯指紋的地方:僅 ML-KEM-768 的公鑰就有 1184 位元組,遠超 X25519 的 32 位元組,因此混合金鑰共享比經典金鑰共享大一個數量級以上。
簽章則是另一回事。ML-DSA(模格數位簽章演算法,FIPS 204)出現在 signature_algorithms 擴充功能中,控制的是握手本身如何被驗證——而非共享金鑰如何推導。客戶端或伺服器可以支援後量子金鑰交換、後量子簽章、兩者兼具,或兩者皆不支援,每一種組合都是 ClientHello 中一種獨特且可觀察的模式。
為何是混合方案,而非純後量子方案
如今 TLS 中每一個已部署的後量子群組都是混合的:它將經典演算法(X25519)與後量子演算法(ML-KEM)結合,而非直接取代 X25519。共享金鑰由兩者共同推導,因此攻擊者必須同時攻破橢圓曲線難題與格難題才能還原它——這是一種對沖策略,防範 ML-KEM 這個相對年輕的標準可能存在尚未被發現的弱點。這種對沖思路,也正是 Cloudflare 那篇文章討論 ML-DSA 的角度:後量子簽章方案比金鑰交換更新、經過的考驗更少,因此等待一個假設中更優的方案是真實的代價,而非只是謹慎。
為何這是一個指紋訊號
指紋識別伺服器不需要任何新的基礎設施就能注意到 PQC——JA3 和 JA4 早已對完整的 supported_groups 和擴充功能清單進行雜湊。改變的是這些雜湊如今編碼的內容:
版本與建置版本定位。 PQC 支援是逐步推出的——Chrome 在特定的發布區間預設啟用了 X25519MLKEM768,其他瀏覽器則按各自的時程跟進。一個提供或不提供該混合群組的 ClientHello,結合 JA4 已讀取的其他一切,不僅能縮小到「這是 Chrome」,還能大致定位到具體是哪個 Chrome 版本。
為偽造客戶端提供的一致性檢查。 TLS 指紋識別已經在機器人偵測中應用的同一套邏輯——握手是否與所聲稱的 User-Agent 應產生的結果相符——現在多了一個目前極具區分度的欄位。一個尚未更新以加入 PQC 群組的爬取函式庫或舊版 TLS 模擬工具,會與聲稱是目前瀏覽器版本的 User-Agent 產生不匹配,就像今天 Python requests 的握手與 Chrome User-Agent 不匹配一樣。
大小本身,而不只是內容,現在也具有資訊量。 由於 ML-KEM 金鑰共享比經典金鑰共享大得多,ClientHello 本身的原始大小就成為一個粗略訊號——一個支援 PQC 的 ClientHello,在任何人解析具體欄位之前就明顯更大。
網路層的一個變數:更大的 ClientHello
更大的 key_share 擴充功能意味著更大的 ClientHello,這在 TLS 層之下會產生連鎖影響。在 TCP 上,TLS 握手訊息本就允許跨越多個 TCP 分段,因此更大的 ClientHello 大體上只意味著握手完成前多傳輸一點資料。在 QUIC 上,TLS ClientHello 搭載在 Initial 封包中,一個大得多的 ClientHello 更可能需要客戶端合併多個 UDP 資料報,或依賴連線的放大限制處理機制——這是一些中間設備和較舊的 QUIC 協定堆疊歷史上處理得不太一致的邊界情況。在符合規範的實作中,這些都不會破壞握手,但這又是一個 PQC 支援以可觀察、依賴具體實作的行為形式呈現出來的地方,而非一次不可見的內部改動。
這對偵測系統意味著什麼
這一切並沒有帶來新的偵測類別——只是在既有類別裡增加了一組新的取值。一個檢查 TLS 指紋一致性的機器人偵測或反詐欺系統,多了一個可以推理的維度:這個客戶端的 PQC 態勢,是否與它所聲稱的瀏覽器與版本應產生的結果相符?在同一工作階段的多個請求之間,這種態勢是否保持一致?一個終止並重新建立自己 TLS 連線的VPN 或攔截代理,會攜帶其自身 TLS 函式庫的 PQC 支援情況(有或沒有),與原始客戶端無關——這與今天已經暴露 TLS 終止代理的破綻如出一轍,只是多了一個欄位可供比對。
從更廣泛的瀏覽器指紋識別視角來看,這是一個網路層訊號,而非 JavaScript 可觀察的訊號——你無法從 navigator 屬性中讀取頁面的 TLS ClientHello。它與 TLS 指紋識別、HTTP/3/QUIC 指紋識別並列,都是伺服器在你的瀏覽器渲染任何內容之前就能看到的又一個資訊片段。
常見問題
後量子 TLS 會讓我的連線變慢嗎?
影響很小,而且主要體現在握手上,而非持續的吞吐量。更大的金鑰共享會增加少量一次性的握手頻寬和運算量;對現代網路上的大多數連線而言,這基本上不可察覺。它更重要的影響場景,是高度受限的網路,或對 ClientHello 分段較敏感的路徑,正如上文所述。
我能透過停用後量子金鑰交換來降低指紋熵嗎?
如果你的瀏覽器暴露了這個選項,你可以這麼做,但這很可能讓你更容易被識別,而非更難。隨著支援 PQC 的群組在目前的瀏覽器版本中成為標準配置,一個明顯缺少它們的 ClientHello,看起來會像是過時的建置版本或被刻意修改過的客戶端——這是拿一個指紋訊號換取了另一個更可疑的訊號。
ML-KEM 和 ML-DSA 是同一回事嗎?
不是。ML-KEM(FIPS 203)是用於金鑰交換的金鑰封裝機制——它作為像 X25519MLKEM768 這樣的混合群組的一部分,出現在 supported_groups/key_share 中。ML-DSA(FIPS 204)是用於驗證握手的簽章演算法,出現在 signature_algorithms 中。兩者都是後量子的、基於格的、由 NIST 標準化的演算法,但它們解決的是不同的問題,出現在 ClientHello 的不同欄位中。
這對 JA3 指紋和 JA4 指紋的影響一樣嗎?
不一樣,比大多數協定變化的差異都更明顯。JA3 依客戶端傳送的實際順序對密碼和擴充功能進行雜湊,因此對某個函式庫如何在既有群組中排列新增的 PQC 群組這一點非常敏感。JA4 會在雜湊前對兩者排序,因此對排序差異具有穩健性,只反映實際的取值集合——包括是否存在 PQC 群組——這使它成為追蹤這一轉變更穩定的選擇。關於 JA3 和 JA4 更全面的差異,參見 TLS 指紋識別詳解。


