TLS Fingerprinting · 子课题 第2页 / 共3页

TLS协议指纹 (中篇 · 指纹家族与提取管线)

本页详解JA3/JA3S、JA4与JA4+家族、JARM、HASSH的算法结构与工程缺陷(含JA4_a各字段语义与扩展随机化的应对),给出采集-解析-存储的提取管线规范(附真实解析器缺陷案例),并讨论TLS 1.3、QUIC、ECH与会话恢复场景下的适配要点。

01 · 指纹家族算法详解

1.1 JA3 / JA3S:五元组与MD5(Salesforce, 2017)

JA3是TLS指纹的奠基方法,由Salesforce检测云团队的John Althouse、Jeff Atkinson、Josh Atkins创建并开源。其对ClientHello提取五个字段,按出现顺序、以短横线连接列表元素、以逗号连接字段,生成待哈希字符串后取MD5:

JA3(客户端)

五元组字段拼接

JA3 = MD5( TLSVersion, CipherSuites, // "-"连接,如 4865-4866-4867 Extensions, // "-"连接 EllipticCurves, // "-"连接 EllipticCurvePointFormats // "-"连接 )
771,4865-4866-4867-…,0-23-65281-…,29-23-24-25,0 └版本 └套件列表 └扩展列表 └曲线 └点格式(示意)

原始实现见Salesforce官方GitHub仓库(salesforce/ja3),提供Zeek脚本与Python解析器,并随仓库提供测试用pcap。

来源:Althouse, Atkinson & Atkins(Salesforce),2017
JA3S(服务端)

ServerHello三元组

JA3S = MD5( TLSVersion, CipherSuite, // 服务端选定单项 Extensions )

JA3S单独使用时判别力有限,但"JA3+JA3S"联合查询可显著缩小实现族范围(如区分CDN后端与源站直连)——这也是指纹查询库(如JA3er)支持双字段检索的原因。

来源:Salesforce JA3官方文档,2017

JA3的工程缺陷:其一,MD5黑盒导致指纹不一致时无法人工诊断差异来源;其二,对GREASE的处理依赖具体实现版本;其三,对TLS 1.3的supported_versions语义支持不佳;其四,顺序敏感——2023年起Chromium对扩展顺序进行随机化(Chrome 110正式启用),JA3在现代浏览器流量上系统性失稳(第1页已述Fastly的实测证据),社区以JA3N(排序归一化)缓解,根治方案是JA4。

1.2 JA4与JA4+家族:分段可读设计(FoxIO, 2023)

JA4由FoxIO发布(John Althouse主导设计),将指纹拆为三段:JA4_a为可读前缀——传输方式(t=TCP / q=QUIC)+ 最高版本(13=TLS 1.3 / 12=TLS 1.2)+ SNI有无(d/i)+ 密码套件数量与扩展数量(各两位十六进制计数,超过99封顶) + ALPN编码(取首个ALPN值的首字符与尾字符,如h2、http/1.1→h1);JA4_b为排序后密码套件列表的截断SHA256(12字符);JA4_c为排序后扩展列表与签名算法的截断SHA256(SNI与ALPN扩展不参与c段——二者的语义已在a段体现;签名算法列表保持原始顺序;规范要求剔除GREASE取值)。排序设计使JA4天然免疫扩展顺序随机化。

JA4 示例结构(官方示例)

来自FoxIO官方文档:t13d1516h2_8daaf6152771_b186095e22b6

t13d1516h2 _8daaf6152771 _b186095e22b6 └─ JA4_a 可读前缀 └─ JA4_b 套件哈希 └─ JA4_c 扩展+签名算法哈希 t=TCP 13=TLS1.3 排序后截断SHA256 排序后截断SHA256 d=含SNI 15=21个套件(0x15) ← 密码套件数量,十六进制 16=22个扩展(0x16) ← 扩展数量,十六进制 h2=ALPN首/尾字符

三段可独立比对:a段快速过滤(如"只可能是HTTP/2浏览器"),b/c段精确定位实现;调试时可直接读出"这是一个走TCP、TLS 1.3、带SNI、ALPN为h2的客户端"。规范另定义JA4_r原始变体(保留未排序的原始列表),供排查与离线比对使用。

来源:FoxIO, JA4+ Network Fingerprinting,github.com/FoxIO-LLC/ja4(示例指纹取自该仓库官方文档)

JA4_a各字段语义速查

位置取值示例语义
第1位t / q传输方式:t=TCP,q=QUIC(HTTP/3)
第2-3位13 / 12协商所得最高TLS版本(13=TLS 1.3,12=TLS 1.2)
第4位d / i是否包含SNI:d=domain(含SNI),i=IP(无SNI)
第5-6位15密码套件数量,两位十六进制(0x15=21个;超过99记为99)
第7-8位16扩展数量,两位十六进制(0x16=22个;超过99记为99)
第9-10位h2 / h1 / 00ALPN编码:首字符+尾字符;无ALPN扩展时记00

JA4+将同一思想推广到更多协议面,形成持续扩展的家族(以下清单以FoxIO仓库README公开列表为准):

变体协议层观测对象典型用途
JA4TLS客户端ClientHello(被动)浏览器/工具/恶意客户端识别,机器人预检主力特征
JA4STLS服务端ServerHello + 选定参数(被动)服务器实现识别、CDN与源站区分
JA4HHTTPHTTP请求头顺序与取值(被动)浏览器指纹补充、headless工具识别
JA4XX.509证书字段(序列号、有效期、扩展、公钥参数)证书生态异常发现、自签/仿冒证书聚类
JA4T / JA4TSTCP客户端/服务端初始窗口、MSS、选项顺序、TTL等操作系统级被动识别(与p0f同类)/ 服务端TCP栈识别
JA4L / JA4LS时序握手往返时序与包长序列距离推断、0-RTT/会话恢复场景补充
JA4SSHSSHSSH握手算法协商SSH实现识别(HASSH思想的现代化重述)
JA4D / JA4NDHCP / NTPDHCP请求指纹 / NTP包特征内网设备识别 / 时间服务实现识别
JA4TScan / JA4Scan主动探测主动TCP/TLS/QUIC扫描授权环境资产与服务端实现测绘

工具支持:Wireshark 4.4起原生内置JA3/JA4客户端指纹显示(tls.handshake.ja4);JA4S等完整JA4+家族可安装FoxIO官方Wireshark插件(ja4.ja4s)。Python/Rust参考实现与Zeek脚本见同一仓库。

1.3 JARM:主动探测范式(Salesforce, 2020)

JA3/JA4是被动方法——必须等到目标主动发起握手。JARM反其道而行:探测者主动向目标IP:端口发送10个精心构造的ClientHello,每个探针在TLS版本、密码套件与扩展组合上各不相同(包括故意声明废弃版本与非常规套件),观察服务器如何处理:是否拒绝、以何种Alert拒绝、协商出什么版本与套件。10次响应的模式被哈希为62字符的JARM指纹。

  • 价值:被动方法看不到"没人连接的服务器";JARM可主动测绘C2基础设施——Cobalt Strike、Metasploit等框架的默认TLS实现有特异响应模式,威胁情报平台常将其用于C2资产发现与聚类;
  • 边界:指纹反映"服务器对探针的响应行为",可被定制配置显著改变;且主动探测本身产生流量,授权边界必须先行确认——这一约束与本学院攻防演练的授权规范一致。

1.4 HASSH:SSH协议的等价物(Salesforce, 2018)

HASSH由Salesforce检测云团队的Ben Reardon创建(Adel Karimi参与贡献,灵感来自JA3),2018年9月开源。它提取SSH_MSG_KEXINIT消息中的密钥交换、加密、MAC、压缩四类算法列表,以分号连接后取MD5,分别生成客户端hassh与服务器hasshServer。SSH在自动化运维、代理跳转与数据外传场景中大量使用,HASSH为无TLS场景提供同等的实现识别能力。可验证的生态事实:Wireshark自3.6.0起内置hassh/hasshServer字段(ssh.kex.hassh);Shodan支持ssh.hassh查询字段;Salesforce原始仓库现由其原作者在Corelight维护活跃分支;Zeek可通过社区软件包将HASSH写入ssh.log。JA4SSH可视为同一思路在JA4+框架内的现代化重述。

1.5 四种方法能力对比

指纹方法六维能力对比(JS绘制)
可读性/被动性/GREASE鲁棒性/ECH兼容性/多协议覆盖/抗伪造难度,满分100 · 本学院基于公开规范的研究性定性评估
说明:评分为研究性定性评估(满分100),依据各方法公开规范的结构特性推导,非实验测量值;用于方法选型参考。

02 · 提取工程管线

2.1 采集点选择:从SPAN到eBPF

指纹质量的上限在采集点决定。可选路径按侵入性与可见性排序:交换机SPAN/RSPAN端口镜像(零侵入但可能丢包、无时序保真)、网络TAP分光(硬件级复制,时序保真,成本较高)、主机侧eBPF/XDP探针(内核态抓取,可与本课题"eBPF实时检测框架"子课题复用同一探针体系,支持五元组过滤与只抓首包降低开销)、以及TLS终结点前采集(可见解密后流量,但失去"被动观察者视角"的证据效力——适合检测、不适合取证叙事)。检测侧推荐eBPF方案:仅对TCP首包或QUIC Initial触发解析,常态开销可忽略。

2.2 解析与归一化:正确性即生命线

解析器的正确性规范(任何一条违反都会导致指纹库污染):

1
流重组

按五元组重组TCP字节流;QUIC需解析Initial包中的CRYPTO帧;分片与乱序必须在指纹计算前完成。

2
GREASE剔除

按RFC 8701规则识别0x?a?a形态取值并从套件/扩展/曲线列表中剔除,保留相对顺序。

3
排序归一化

JA4的b/c段对列表排序后再哈希——必须实现为稳定归一化,否则浏览器扩展随机化会使同一实现产生不同指纹(JA3失稳的教训)。

4
版本语义

TLS 1.3以supported_versions扩展为准而非legacy_version;QUIC按JA4的q前缀规则处理传输参数。

提取管线数据流(JS绘制)
被动采集仅触碰握手首包;载荷不落盘
框架为迪妙网络空间安全学院教学化整理:采集层只提取握手特征并丢弃载荷,满足最小化采集原则(见第04节)。

真实世界的解析器缺陷(均已公开修复,可直接溯源):① nDPI的JA4实现曾把ALPN"http/1.1"的首尾字符误取为"ht"而非"h1"(ntop/nDPI Issue #2914,2025年7月),导致其指纹与Wireshark等其他实现互不兼容;② Wireshark 4.4.2修复JA4_c空字段哈希错误(Issue 20066)、4.4.4修复空密码套件列表场景的JA4错误(Issue 20394,均见官方发布说明)。这印证"解析器正确性即生命线"绝非口号——同一握手在不同解析器中产出不同指纹,是评估指纹库互操作性时必须实测的事项。

2.3 编码、存储与版本管理

生产指纹库应记录:指纹值、规范版本、采集点类型、解析器版本、首末观测时间与观测计数。规范仍在演进——JA4+文档持续修订,不同版本解析器对同一握手的计算结果可能不同,因此"指纹+规范版本"是不可拆分的复合主键。社区库(JA4DB)采用可信度评分与众包验证机制缓解标注质量问题;自建库则应保留原始ClientHello样本哈希,以便规范升级时重算指纹。表结构示意:

fingerprint | method | spec_ver | parser_ver | vantage | first_seen | last_seen | count | sample_sha256 ------------+--------+----------+------------+---------+------------+-----------+-------+-------------- t13d1516h2_…| JA4 | v3 | ja4-py2.1 | ebpf | 2026-08-02 | 2026-09-05| 11842 | a91f…e0 (示意)

解析器正确性自检清单:① GREASE剔除——对固定实现多次握手,剔除后字段列表恒定;② 排序归一化——对随机化扩展顺序的输入,排序后哈希恒定;③ 官方测试向量——以FoxIO仓库附带的pcap样例与预期输出做自动化回归(仓库自带pytest比对脚本);④ 分桶——完整握手与PSK恢复握手分别建库;⑤ 版本记录——指纹值与规范版本、解析器版本作为复合主键留存;⑥ 交叉验证——同一pcap分别用Wireshark与自研解析器计算,比对结果应完全一致。

2.4 性能与资源预算

指纹管线位于流量路径上,性能设计直接决定可部署性。工程要点:①采集层"首包触发"——eBPF探针仅在SYN/ACK后首个TLS记录(或QUIC Initial)到达时唤醒解析逻辑,常态CPU开销趋近于零,这也与本课题"eBPF实时检测框架"子课题的探针体系同源;②解析层无载荷驻留——握手特征提取后即可释放缓冲,单条流内存占用为O(1);③存储层按键去重——以"指纹值+规范版本"为复合键,观测计数累加,热数据常驻内存、冷数据批量落盘。

公开吞吐基准可参考:nDPI官方CHANGELOG持续披露单核近似口径的测试数据——v3.4约1.29M pps / 3.35 Gbps,v4.0约3.35M pps / 8.68 Gbps(以官方记录为准);其开销主体在协议识别而非指纹计算本身,说明"握手特征提取"在千兆级链路上具备工程可行性。自建系统上线前应按目标链路的pps与并发连接数压测,并将GREASE剔除、排序归一化的回归测试纳入发布门禁。

2.5 哈希截断、冲突概率与许可边界

冲突定量分析(可直接推导复核)。JA4_b与JA4_c各取SHA-256摘要的前12个十六进制字符,即48比特输出空间。按生日界估算,独立均匀指纹约需2^24(≈1.7×107)条量级才会出现"任意两指纹碰撞"的期望;JA4DB与JA3er公开库当前十万条量级距该阈值尚有两个数量级以上余量。且JA4以"a_b_c三段联合"作为完整指纹,b段或c段单独冲突不会导致整体误判;工程上可保留JA4_r原始列表用于碰撞复核。JA3使用完整MD5(128比特摘要空间),其工程痛点始终是可读性与顺序敏感性,而非碰撞风险。

许可边界(商用集成前必读):FoxIO将核心JA4方法以BSD 3-Clause许可发布;JA4+家族中的其余方法(JA4H、JA4S、JA4X、JA4T等)采用FoxIO自有许可且部分专利在审——商业产品集成前须查阅github.com/FoxIO-LLC/ja4仓库的Licensing说明。nDPI作者在公开技术分享中亦专门指出了JA4核心与JA4+其他成员的许可差异。这一区分直接影响选型:Wireshark内置JA4、Zeek JA4脚本等开源路径,与商业产品所需授权范围并不相同,采购评估时应将其列为尽调项。

03 · TLS 1.3 / QUIC / ECH 适配要点

TLS 1.3下的指纹适配

TLS 1.3(RFC 8446)握手为1-RTT:ClientHello的supported_versions扩展宣告真实版本,legacy_version恒为0x0303;ServerHello之后全部消息加密,被动观察者失去证书明文。指纹层面:密码套件列表仅剩5个AEAD套件可选,判别信息密度下降,扩展组合(key_share、supported_versions、psk_key_exchange_modes、signature_algorithms的取舍)成为主要判别维度;JA3原始五元组在1.3下仍可计算但稳定性受扩展随机化侵蚀,JA4_a直接编码版本语义且列表排序,因而更稳健。

关键来源:Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", RFC 8446, IETF, 2018.

QUIC/HTTP3下的指纹适配

QUIC(RFC 9000)将传输与加密合并:版本协商、传输参数与TLS握手共存于Initial加密包。JA4对QUIC客户端以"q"前缀区分,其判别维度除TLS参数外还包括QUIC版本与传输参数的组合。HTTP/3(RFC 9114)使浏览器指纹体系从纯TLS扩展到"TLS+QUIC"联合观测,单一维度仿冒难度显著上升。探测侧注意:QUIC基于UDP,传统TCP重组管线需扩展支持CRYPTO帧提取。

关键来源:Iyengar & Thomson, "QUIC: A UDP-Based Multiplexed and Secure Transport", RFC 9000, 2021;Thomson & Turner, "Using TLS to Secure QUIC", RFC 9001, 2021;Bishop, M., "HTTP/3", RFC 9114, 2022.

ECH(RFC 9849)下的指纹适配

ECH以HPKE(RFC 9180)加密的ClientHelloInner封装真实SNI与目标扩展,外层ClientHelloOuter仅暴露public_name;ECHConfig公钥经HTTPS/SVCB DNS记录(RFC 9460)与配套的配置发布机制(RFC 9848)分发。影响分层:域名级明文识别失效;但外层ClientHello的密码套件、扩展结构仍由真实客户端实现决定——指纹信号完整保留,只是失去与明文域名的绑定。JA3/JA4从设计上不读取SNI明文(JA4_a仅用计数与长度编码),ECH前后其值域稳定。ECH同时要求客户端发送GREASE ECH扩展(伪造的加密负载),使网络中间盒无法简单按"是否含ECH扩展"分流,进一步模糊识别边界。检测实践应将"指纹命中+目的IP信誉"替代"指纹命中+明文SNI"作为ECH时代的主查询模式。

关键来源:IETF, "TLS Encrypted Client Hello", RFC 9849, 2026年3月(由draft-ietf-tls-esni演进);"SUD for TLS ECH"(ECHConfig发布),RFC 9848, 2026;"Service Binding and Parameter Specification via the DNS",RFC 9460, 2023;FoxIO JA4+规范。

会话恢复与0-RTT的影响

TLS 1.3会话恢复通过pre_shared_key扩展实现,0-RTT通过early_data扩展宣告。两者改变扩展组合与包序列:恢复握手中key_share可能缩减、Certificate消息缺席。JA3/JA4计算以ClientHello为对象,恢复握手同样产生可计算指纹,但其值域与完整握手不同——指纹库必须区分"完整握手指纹"与"恢复握手指纹"两类样本,否则同一客户端会被聚成两个簇。EarlyData的流量形态(首包载荷较大)则可作为JA4L时序特征的补充信号。

04 · 隐私与合规边界

TLS指纹处于"网络监测"与"设备识别"的交叉地带,部署时必须回答三个合规问题:采集是否最小化——建议只提取握手特征并丢弃载荷,eBPF探针开启首包过滤;用途是否限定——指纹数据仅用于授权范围内的安全检测,不得用于个人追踪(指纹本身通常不指向自然人,但与账号日志关联后即具备画像能力);是否可审计——留存策略、访问控制与导出审批应成文。对迪妙网络空间安全学院的企业培训场景,我们将其浓缩为一句可执行的话:"指纹是线索,不是结论;采集有边界,使用有授权。"

小结:本页完成了从算法(JA3/JA4/JARM/HASSH)到工程(采集/解析/存储)再到协议演进适配的体系构建。第3页将收束于检测应用实践:C2识别、机器人预检、对抗与误报控制、评估基准与全部参考文献。

终审核验声明:本页算法细节(JA3五元组、JA4三段式与a段字段语义、JARM十探针、HASSH四类算法列表)、解析器缺陷案例(nDPI Issue #2914、Wireshark 4.4.2/4.4.4)与工具版本信息,已于2026年9月15日对照官方仓库与发布说明逐条复核。