JA4H、JA4T、JA4L 把 TLS 指紋擴展到 HTTP 請求、TCP 交握與連線延遲。本文講清各自原理,以及層與層之間的矛盾為何最能揭露代理與機器人。
TLS 指紋識別一文介紹了 JA3 和 JA4——從單次 TLS ClientHello 中讀出的指紋。但 JA4 從來就不是孤立存在的。它的創造者 FoxIO 把它作為一個更大家族的一部分發布,這個家族名為 JA4+,其中大多數成員採集指紋的對象與 TLS 毫無關係:HTTP 請求本身、其下的 TCP 交握,甚至封包在用戶端與伺服器之間往返所需的時間。每一層都被獨立讀取,而下文會看到,真正的威力恰恰展現在各層彼此矛盾的時候。
核心要點
- JA4+ 是一整套指紋,而不是一個指紋。 JA4 涵蓋 TLS ClientHello;JA4H 為 HTTP 請求產生指紋,JA4T 為 TCP 交握產生指紋,JA4L 為連線延遲產生指紋——每一個都讀取同一連線中不同、獨立的一層。
- 各層彼此獨立,這正是關鍵所在。 User-Agent 和 TLS 指紋都顯示「Windows 上的 Chrome」,TCP 指紋卻顯示「Linux 核心」——這是教科書等級的代理或反偵測瀏覽器破綻,單看任何一層都發現不了。
- JA4T 在任何加密開始之前就讀取 SYN 封包。 視窗大小、TCP 選項順序、MSS 和視窗縮放值都來自作業系統網路堆疊,因此 JA4T 標識的其實是「核心」——與TCP/IP 指紋識別一文所述是同一個信號,只是 JA4T 把它整理成了結構化、可排序的字串。
- 該格式刻意做到人類可讀。 不同於 JA3 輸出的那種不透明 MD5 雜湊,每一個 JA4+ 指紋都被劃分為
a_b_c結構,其中前綴部分憑肉眼就能讀懂一部分——分析人員也能只比對字串的一部分,而不必整串比對。 - 授權分成兩套。 JA4 本身開源(BSD 3-Clause),FoxIO 表示不會為它申請專利。JA4H、JA4T、JA4L 等其餘「+」成員正在申請專利,採用 FoxIO License 1.1 授權:學術與企業內部使用沒有問題,但要把它們放進販售的產品或代管服務,就需要購買 OEM 授權。
- 這些都不會暴露給頁面 JavaScript。 JA4+ 是由伺服器、CDN 或網路設備讀取原始封包後計算出來的——像我們的指紋偵測這樣的用戶端工具無法顯示你自己的 JA4H 或 JA4T,因為你的瀏覽器根本看不到自己剛發出的封包。
快速回顧:JA4(TLS)
TLS 指紋識別一文已詳細講過,這裡只用三句話概括。每一次 HTTPS 連線都以一則明文 ClientHello 開始,其中列出了加密套件、擴充功能與橢圓曲線,其排列順序由用戶端的 TLS 函式庫決定,而非使用者。JA4 把這些值排序、剝除 GREASE 雜訊後進行雜湊,產生類似 t13d1517h2_8daaf6152771_cb7bf5808d99 的指紋——在多次連線間保持穩定、前綴可讀,並能標識具體使用的 TLS 函式庫。以下各節讀取的都是同一連線中不同的層。
JA4H:為 HTTP 請求產生指紋
JA4H 讀取用戶端發出的實際 HTTP 請求——看的不是內文,而是請求本身的形態(對 HTTPS 而言,由終止 TLS 的一方讀取:伺服器本身,或前方的 CDN)。根據 FoxIO 的 JA4H 規格,指紋的可讀前綴依序編碼:請求方法(取前兩個字母並轉小寫,GET 為 ge,POST 為 po)、HTTP 版本(HTTP/1.1 為 11,HTTP/2 為 20)、是否帶 Cookie 標頭(c/n)、是否帶 Referer 標頭(r/n)、兩位數的標頭數量(不計 Cookie 與 Referer),以及 Accept-Language 值的前四個字元(en-US 記為 enus,缺少該標頭時記為 0000)。前綴之後是三段短雜湊,分別對應:依送出順序排列的標頭名稱、Cookie 欄位名稱,以及 Cookie 欄位名稱連同其值。其中 Cookie 欄位名稱的雜湊對同一網站的所有訪客通常相同,名稱加值的雜湊則因使用者而異。
FoxIO 公開的指紋對照表裡有一個真實案例:IcedID 惡意軟體植入程式產生的指紋是 JA4H=ge11cn020000_9ed1ff1f7b03_cd8dafe26982。解讀一下:HTTP/1.1 上的 GET 請求,帶 Cookie、沒有 Referer、只有另外兩個標頭,而且完全沒有 Accept-Language(結尾的 0000)。這兩點都很醒目。真實瀏覽器通常會以固定、各瀏覽器特有的順序送出十個以上的標頭,而標頭順序正是第二段雜湊所記錄的內容;FoxIO 也指出,缺少 Accept-Language 強烈顯示用戶端並非由真人操作的瀏覽器。這與 HTTP/2 指紋識別一文討論的標頭順序信號是同一個思路,只是推廣到所有 HTTP 版本,而非侷限於某一個。如果你要跨時間比對指紋,有一項最新變化值得留意:2026 年 8 月 27 日的一項修正讓 FoxIO 的 Rust 實作在計算 JA4H 時排除 HTTP/2 自身的偽標頭(:method、:path、:scheme、:authority),因為它們是協定強制要求的,而非用戶端的選擇——所以該工具在修正前後產生的 HTTP/2 指紋無法直接對上。
JA4T:為 TCP 交握產生指紋
JA4T 讀取的是開啟 TCP 連線的 SYN 封包——與TCP/IP 指紋識別一文所述是同一層,只是被打包進 FoxIO 結構化的 JA4 格式,而非 p0f 那種簽章比對方式。它把 TCP 標頭中的四個值組合起來:通告的視窗大小、按網路堆疊送出順序排列的 TCP 選項(以其數字類型編號表示——2 代表 MSS,1 代表 NOP 填充,3 代表視窗縮放,4 代表 SACK-permitted,8 代表時間戳記)、最大分段大小,以及視窗縮放係數。
FoxIO 給出的 Windows 11 用戶端範例是 JA4T=64240_2-1-3-1-1-4_1460_8:64240 位元組的視窗、按 MSS–NOP–視窗縮放–NOP–NOP–SACK-permitted 順序排列的選項、1460 的 MSS,以及值為 8 的視窗縮放。這些都與 TLS、HTTP 或 User-Agent 標頭無關——它們由作業系統核心寫入,那時瀏覽器連一個加密位元組都還沒送出。細節裡資訊量很大:FoxIO 指出,Windows 不送出時間戳記選項(8),而類 Unix 系統的協定堆疊會送出,所以上面範例中沒有 8 本身就是 Windows 的特徵。MSS 欄位除了反映作業系統,也反映網路路徑:標準乙太網路 1500 位元組的 MTU 對應 1460 的 MSS;更低的數值(例如 1380)代表存在加密或隧道開銷。FoxIO 還舉過一個類 Unix 指紋的例子,其 MSS 為 1424,也就是多出 36 位元組開銷,可能是未加密的隧道或代理。工具層面,2026 年 8 月 27 日的一項修正讓 FoxIO Rust 實作的數字欄位格式與其 Wireshark、Zeek 實作保持一致——如果你要比對不同工具產生的 JA4T 字串,這點值得留意。
JA4L:為延遲產生指紋
JA4L 是套件中的異類——它採集的不是任何協定欄位,而是交握的時間。把 TCP 三向交握的三個封包記為 A(SYN)、B(SYN-ACK)、C(ACK),由觀測點記錄各自的時間。FoxIO 定義 JA4L-C =(C − B)/ 2,估算觀測點到用戶端的單向延遲;JA4L-S =(B − A)/ 2,估算到伺服器一側的單向延遲。兩者單位皆為微秒,並各自配上該方向封包上觀察到的 TTL。緊鄰伺服器的感測器會得到有意義的 JA4L-C 與接近零的 JA4L-S,反之亦然。由於它只讀取封包時間與 IP 標頭,無論流量是否加密都能使用。
這兩個數字都有物理意義。光纖中的信號不可能快過光速——FoxIO 取約每微秒 0.128 英里(約 0.2 公里),再乘上反映實際路由的傳播延遲係數——因此延遲讀數給出了對端物理距離的上限,這也是 FoxIO 把 JA4L 同時當作位置測量來介紹的原因。TTL 則提供第二條線索:不同作業系統的初始 TTL 不同(Linux 與 macOS 通常為 64,Windows 為 128),所以觀察到的 TTL 既能提示躍點數,也能暗示發送方的作業系統類別——又多了一個可能悄悄與 User-Agent 矛盾的欄位。
因此,JA4L 可以用來交叉驗證位置聲明。如果某條連線的 IP 位址定位在另一個大洲,交握卻在一兩毫秒內完成,那就有問題——不管 IP 資料庫怎麼說,完成交握的機器在物理上就在附近。反過來的情況證據力較弱,但仍然有用:第三層 VPN 會把用戶端自己的交握封包端對端轉發,因此測得的延遲包含了通往真實使用者的那段隱藏路程;如果讀數遠大於出口 IP 位置所能解釋的範圍,就暗示對方比看起來離得更遠。(網路壅塞也會推高延遲,所以「低到不可能」的讀數才是更強的信號。)
補齊套件:JA4X、JA4SSH 與其他成員
還有幾名成員雖然不在瀏覽器隱私讀者的日常關注範圍內,也值得認識一下。JA4X 為 TLS 伺服器(在雙向 TLS 場景中也可以是用戶端)出示的 X.509 憑證產生指紋——但 FoxIO 明確說明,它記錄的是憑證如何產生,而不是憑證裡的具體值。因此,同一套工具簽發的憑證即使名稱和金鑰各不相同,也會歸到同一個指紋下,這對跨攻擊活動追蹤惡意軟體 C2 基礎設施很有用。JA4SSH 把同樣的思路用在 SSH 上:以滾動視窗(預設每 200 個封包)依據封包長度、數量與 ACK 模式概括一段加密工作階段,無需解密就足以區分互動式 shell、檔案傳輸與反向 shell。其餘成員涵蓋伺服器端與其他協定——JA4S(TLS ServerHello 回應)、JA4TS(伺服器的 TCP SYN-ACK)、JA4TScan(主動式 TCP 掃描器)與 JA4D(DHCP)。這些都不直接涉及瀏覽器,但都遵循與 JA4H/T/L 相同的設計理念:採集用戶端在結構上穩定的特徵,而不管它自稱是什麼。
為什麼各層出現分歧才是關鍵
本站目前討論過的每一種指紋——Canvas、WebGL、TLS——回答的都是「這一個信號說明用戶端是什麼」。JA4+ 真正的貢獻,是把它變成一次交叉驗證:讀取同一連線中的若干獨立層,看它們講的是不是同一個故事。
舉一個具體例子:某個爬蟲專案跑在 Linux 伺服器上,送出 Windows 版 Chrome 的 User-Agent,並用 TLS 偽裝函式庫讓自己的 JA4 與 Chrome 完全一致。這足以騙過只檢查 TLS 的驗證。但同一台伺服器的核心仍會寫下自己的 TCP SYN 封包——JA4T 讀出的是 Linux 的視窗大小、選項順序與 MSS,而這些偽裝函式庫通常不會去動它們,因為它是在作業系統網路堆疊之上運作的。同時記錄兩種指紋的偵測系統會看到:一個自稱 Windows 上的 Chrome 的請求,走的卻是一次明顯來自 Linux 的 TCP 交握。這種矛盾遠比單獨任何一個指紋都更難修補——攻擊者必須同時控制偽裝函式庫、核心 TCP 堆疊,以及 HTTP 用戶端的標頭順序,少控制哪一層,破綻就會出現在哪一層。這與機器人偵測技術以及 JA3/JA4 如何與 TCP/IP 指紋識別疊加中描述的原則是一致的——可觀察層之間的不一致,比任何單一異常都更有說服力。
格式的可讀性:為什麼 JA4+ 字串是可讀的
JA3 的輸出是一個不透明的 MD5 雜湊——適合精確比對,但對著日誌行看一眼毫無意義。FoxIO 為每一個 JA4+ 指紋都設計了刻意可讀的 a_b_c 結構:一個可以明文解讀的前綴(方法、版本、計數、旗標),後面跟著一個或多個短雜湊,用來表達那些過於細碎、無法直接拼出來的部分。這種可讀性並非裝飾。FoxIO 的 README 寫道,這種格式允許「只用 ab、ac 或 c」進行威脅獵捕與偵測——例如,分析人員可以只比對可讀前綴加上其中一段雜湊,而忽略另一段。
這也帶來了實際的好處:由於格式是公開規定的,而不是靠逆向工程推出來的,第三方可以打造相容的實作。FoxIO 的 README 列出了原生支援它的工具與服務,包括 Suricata、Arkime、ntopng、Cloudflare、AWS CloudFront 與 WAF,以及 Google Cloud Armor;Wireshark 和 Zeek 則透過 FoxIO 參考儲存庫中維護的外掛取得支援。互通的前提是每個實作都輸出逐位元組相同的字串,這需要持續維護:2026 年 8 月 27 日,FoxIO 在同一天合併了兩項正確性修正——Rust 實作中 JA4T 的數字欄位重新與 Wireshark、Zeek 的輸出對齊,JA4H 的 Rust 指紋改為排除 HTTP/2 偽標頭。這提醒我們:任何關於這些指紋確切格式的描述,都只對它所依據的實作版本有效。
授權:為什麼生態一分為二
JA4 本身——TLS 用戶端指紋——以 BSD 3-Clause 條款發布,與 JA3 當年的條款相同,FoxIO 並聲明對它沒有專利主張、也不會申請專利。套件中的其餘成員(JA4S、JA4H、JA4L、JA4X、JA4SSH、JA4T 等)都在申請專利,並採用 FoxIO License 1.1 授權:允許學術與企業內部使用,但要在產品或代管服務中將這些方法變現,就需要 OEM 授權。這正是有些工具與服務只實作 JA4、跳過套件其餘部分的原因之一——這既是技術選擇,也是授權層面的決定。
你實際能做些什麼
JA4H、JA4T 和 JA4L 都無法被頁面 JavaScript 讀取。三者都是在流量抵達時計算的——依據 TCP 標頭與交握時間,以及 TLS 終止後的 HTTP 請求——計算者是網路路徑上的某個環節:伺服器、CDN 邊緣節點或監控設備。這代表我們自己的指紋偵測工具,和所有純用戶端的指紋示範一樣,無法向你展示你自己的 JA4H 或 JA4T 字串:瀏覽器根本看不到作業系統剛剛替它送出的封包。
你可以這樣做:
- 即時查看你的 TLS 層 JA4。 TLS 指紋識別頁面會顯示我們的邊緣節點從你目前連線中觀察到的 TLS 版本、加密套件,以及(若可取得)JA4 雜湊。
- 檢查交叉驗證中瀏覽器那一半。 我們的機器人偵測會尋找瀏覽器內的自動化痕跡與無頭瀏覽器洩漏,指紋偵測則展示網站可與網路層指紋搭配使用的 Canvas、WebGL 與字型信號。
- 自己擷取其餘部分。 用 Wireshark 搭配 FoxIO 的 JA4+ 外掛記錄自己的流量,就能看到 JA4T 和 JA4L;JA4H 需要明文的 HTTP 請求,因此只會出現在未加密的 HTTP 流量中,除非你同時讓 Wireshark 解密 TLS。
與本站其他文章的邊界
- TLS 指紋識別詳解涵蓋的是 ClientHello 本身的 JA3/JA4——本文假設讀者已了解這一層背景。
- TCP/IP 指紋識別一般性地討論從 IP/TCP 標頭偵測作業系統,獨立於 JA4T 的命名與格式。
- HTTP/2 指紋識別涵蓋的是 Akamai 指紋——SETTINGS 訊框、偽標頭順序——這是與 JA4H 不同的另一種 HTTP 層簽章。
- HTTP/3 與 QUIC 指紋識別涵蓋的是 QUIC 自身的傳輸參數指紋。
- 後量子 TLS 指紋識別涵蓋的是 ML-KEM 金鑰交換如何重塑 ClientHello 的大小與欄位。
- 如何偵測 User-Agent 偽裝從 User-Agent 的角度討論了同樣的跨層不一致原則。
本文專門講的是 JA4+ 家族作為一個統一套件,以及為什麼把它各層放在一起讀——而不是只讀其中任何一層——才真正有用。
常見問題
JA4H 和 HTTP 標頭順序指紋識別是一回事嗎?
關係密切,但並不完全相同。JA4H 是 FoxIO 為 HTTP 請求指紋識別制定的一套特定、標準化格式——一個明確定義的前綴加上若干雜湊段,公開發布是為了讓多個工具能夠產生並比對同一個字串。「HTTP 標頭順序指紋識別」是它所基於的更一般性技術;其他工具與偵測系統會以各自互不相容的格式計算類似的信號。
VPN 會改變我的 JA4T 指紋嗎?
部分會變,而且取決於你用的是 VPN 還是代理。全通道 VPN(WireGuard、OpenVPN、IPsec)轉發的是你自己作業系統建構的 TCP 封包,所以 JA4T 中的視窗大小、選項順序與視窗縮放仍然描述的是你的核心。通常會變的是 MSS:隧道封裝開銷會把它壓到一般乙太網路連線的 1460 以下,FoxIO 就把 1380 這類數值列為加密或隧道的跡象。代理則不同——它會自己與網站建立一條新的 TCP 連線,因此 JA4T 描述的是代理伺服器的作業系統,而不是你的。無論哪種情況,一個看起來像隧道或資料中心 Linux 主機的 JA4T,配上一個自稱一般消費級瀏覽器的 TLS 指紋,都屬於網站如何偵測 VPN 與代理中提到的信號。
我能在哪裡查到自己的 JA4 系列指紋?
你可以在本站的 TLS 指紋識別頁面看到自己即時的 JA4(TLS)指紋,因為這一項是從你的連線在伺服器端計算出來、再展示給你的。JA4H、JA4T 和 JA4L 則需要一個能讀取原始封包或完整 HTTP 請求的工具——它們不像 TLS 交握指紋那樣,可以透過一個簡單的用戶端小工具直接展示出來。
為什麼一家公司會為 JA4+ 付費授權,而不是直接用 JA3?
因為 JA4+ 的設計解決了 JA3 的實際問題——抗 GREASE 干擾、可排序且可讀的輸出,以及涵蓋 JA3 從未觸及的層——這些價值足以讓安全廠商圍繞它打造產品。FoxIO License 1.1 本就允許免費用於學術與企業內部;只有當公司在產品或代管服務中將 JA4+ 方法變現時,才需要 OEM 授權。JA4 本身仍採用 BSD 條款,所以只需要 TLS 層指紋的廠商根本不必申請授權。


