热门库与 BlankTrail Proxy 的浏览器指纹比较:TLS、HTTP/2 与 HTTP/3

TLS、HTTP2/HTTP3、Chrome154、Edge154、Firefox156、Mac 与 iPhone 的 Safari、Android 和 TLS 会话恢复:库的真实测试、原生配置设置,以及 BlankTrail 与旧版软件的配合。

User-Agent 中可以写上 Chrome/154.0.0.0,但服务器先看到的是 TLS 握手,然后是 HTTP/2 参数,最后才是请求头。如果这些层面不一致,“Chrome 154”这个字符串并不能让 HTTP 客户端变成 Chrome。

我们比较了主流公开浏览器网络指纹模拟库与 BlankTrail Proxy,涵盖现成配置、模拟 Chrome 154、Firefox 156、macOS 和 iPhone 上的 Safari、Android 上的 Chrome,以及重复连接、HTTP/2 和 HTTP/3。我们还考察了一个实际问题:能否通过原生支持的设置切换到所需版本,而不必修改库本身,以及接入现有技术栈有多难?

研究数据截至 2026 年 10 月 4 日。 测试包含 Windows、Linux 和 macOS 发出的真实请求、服务端测量、TCP 与 QUIC ClientHello,以及真实浏览器抓包。简要公开检测可使用 BlankTrail /client,详细分析则可通过独立公开服务复现。检测器摘要与原始字段比较分别评估。

统一比较 TLS、HTTP/2、QUIC/HTTP/3、浏览器配置与请求头的方法。
统一比较 TLS、HTTP/2、QUIC/HTTP/3、浏览器配置与请求头的方法。

服务器究竟比较什么

TLS 指纹取决于客户端如何构造 ClientHello,包括密码套件的集合与顺序、扩展及其内容、支持的组、签名算法、ALPN、GREASE、证书压缩、ALPS 和 key share。HTTP/2 的关键细节包括 SETTINGS 及其顺序、WINDOW_UPDATE、伪头字段顺序和优先级参数。HTTP 层还包括 User-Agent、Client Hints 和与请求上下文相关的头字段。

JA4 是有用的摘要,并不是连接的完整描述。 连续几个 Chrome 版本共用一个 JA4 很正常。我们的参考抓包中,Chrome 152、153 和 154 的首次握手 JA4 及基础 HTTP/2 指纹相同。仅凭这些值相同,既不能确认具体版本,也不能证明扩展内容完全一致。例如,JA4 不保留以下扩展的完整载荷: trust_anchors ,并在计算相关哈希部分时排除 GREASE。算法说明见 JA4 仓库.

我们如何比较这些客户端

目标包括 Chrome154、Edge154、Firefox156、Safari26 和移动端配置。我们以真实浏览器抓包为基准,比较 TLS、HTTP/2、HTTP/3 原始字段、请求头和重复连接,测试了现成预设及原生支持的手动配置。JA4 相同或 /client 未提示问题,都不能代替原始字段分析。

测试方法、参考版本与测量条件

各库在独立测试目录中运行,BlankTrail 则通过 API 调用。主要配置均在同一个客户端会话内连续发出四次请求。测试端点主动关闭连接,使下一次请求能够建立新的 TLS 连接并使用已获得的 ticket。在现有 HTTP/2 会话上再次请求,不算 TLS 会话恢复测试。

每种配置都保存了以下端点的响应: /client 以及服务端记录,包括 TLS 字段、PSK 是否被接受、HTTP/2 SETTINGS、连接窗口和伪头字段顺序,并将简要检测结果与原始数据核对。

Chrome154 的首次握手使用 Windows 上真实的 Chrome154.0.8037.93 和独立无头配置测量。完整 ClientHello 与会话恢复使用官方 Stable 安装包中 Chrome154.0.8037.57 的已有抓包,抓包时浏览器在 Xvfb 下以有界面模式运行。安装包来源与 SHA256 均已核验。

TCP 接收端在握手完成前保存 ClientHello,主动关闭连接不计为客户端错误。比较的是稳定参数与结构,随机密钥、random 和 session ID 本就应当不同。GREASE 检查是否存在、位置与随机排序,trust_anchors 则检查标识符集合。

HTTPX 和 primp 对主动关闭连接的端点重复请求时,部分请求在处理已关闭的 HTTP/2 连接时出错。此类错误没有计为指纹不匹配,相关行只列出实际获得的网络记录,并单独标注测试未完整完成。

我们测试了 20 个客户端,涉及浏览器配置、TLS 原始字段、HTTP/2 和 HTTP/3、请求头及重复连接行为。基准来自真实 Chrome154、Edge154、Firefox156、Safari 26.6.2 和移动浏览器的抓包。仅 JA4 相同不算通过,必须比较稳定字段与协议行为,确认范围在结果旁注明。

浏览器各列测试可用的现成配置,如有相应 API,也测试手动参数。在同一端点上,分别使用 Chrome154、Safari 26.6.2、Firefox156、Edge154 和 Chrome Android154 的 UA 连续请求,保存原始 ClientHello 及服务端 TLS/H2 字段。Go 系列在请求间关闭空闲连接,但保留客户端及其缓存。Windows curl 还测试了同一进程中的四个 URL。Node 内置 fetch 单独测试,不替换 dispatcher。只修改 UA 不算配置传输层指纹。

配置版本为什么重要

在 StatCounter 样本中,Chrome154 发布 9 天后,在可识别版本号的桌面 Chrome 流量中占比超过一半,Chrome153 则用了 13 天。旧预设很快就不再代表主流流量。需要更新整个配置,而不只是 User-Agent 中的版本号,当然,版本旧本身并不能证明是自动化。不过我们观察到,浏览器版本对大多数反欺诈系统非常重要,落后超过三个大版本会增加通过反机器人检测的难度。

Chrome 新版本采用速度,依据 StatCounter 每日数据计算。来源:gs.statcounter.com,CC BY-SA 3.0。
Chrome 新版本采用速度,依据 StatCounter 每日数据计算。来源:gs.statcounter.com,CC BY-SA 3.0。
数据来源与局限

计算依据以下每日数据: StatCounter 桌面端/全球,9 月 8 日至 10 月 1 日,范围为可识别版本号的 Chrome 流量,不含 Android。占比基于页面浏览量,并非安装量或独立用户数。方法说明: FAQ StatCounter,图表采用 CC BY-SA3.0 许可。

常规 Chrome154 Stable 于 9 月 22 日发布,从 Chrome153 起,大版本发布周期缩短为两周。来源: Chrome154 发布公告, Chrome 发布周期.

我们测试了哪些方案

我们比较公开的 TLS 模拟方案、其封装库,以及作为对照的普通 HTTP 客户端。排名依据测试能力,而非流行程度,因为没有可比的用户数量数据。同一核心的封装库不视为独立 TLS 引擎。

方案/测试版本技术栈与集成如何切换配置
curl-impersonate 和 活跃维护的分支,通过 curl_cffi 0.16.3CLI/libcurl 和 Python,便于编写脚本,但必须使用 impersonate 构建,普通 curl 并不等价。提供现成目标、libcurl 参数,以及封装层的 JA3/Akamai 和 extra_fp。该系列通过 curl_cffi 测量,没有单独运行原始分支的二进制程序。
curl_cffi 0.16.3Python,接口接近 requests,支持同步/异步,需要随包提供的原生 libcurl。impersonate, ja3, akamai, extra_fp。测试版本没有现成的 chrome154 配置。
uTLS 1.8.2Go,偏底层。控制 ClientHello,HTTP/2 和请求头需另外协调。Hello 配置、HelloCustom、ApplyPreset、ClientHelloSpec。 HelloChrome_Auto 在此版本中指向 Chrome 133,而非当前 Stable。
Go tls-client 1.16.0Go 及用于封装的原生核心,TLS 与 HTTP/2 集成在一起,需要替换代码中的 HTTP 客户端。提供现成 ClientProfile、PSK 变体和自定义配置。最新现成 Chrome 配置为 152,没有名为 154 的配置。
Python tls-client 1.0.1Python,简单的 Session API 搭配原生库。封装版本并不能反映 Go 核心是否最新。client_identifier 及自定义 TLS/HTTP2 参数,测试发行包的 Chrome 预设最高到 120。
noble-tls 0.1.9 / native 1.16.0Python 异步接口。原生 tls-client 与 Python 包分别更新,为复现结果必须固定核心版本。预设枚举、公开的 client_identifier 和自定义设置。已加载核心支持 152/152_PSK,尽管封装层枚举滞后。
CycleTLS 2.0.5Go/Node.js。Node 会启动辅助进程,需要管理其生命周期。JA3、JA4R 和 HTTP2Fingerprint。手动配置取决于核心本身支持哪些扩展。
rnet 2.4.2Python 原生客户端,支持同步/异步。旧发行包不能直接视为最新版 wreq。Impersonate 枚举,测试的 Chrome 预设为 137,没有 Chrome154 名称。
wreq, Python 0.12.3Rust 及 Python 绑定,支持同步/异步,浏览器与平台选择方便,但 API 与 requests 不同。Emulation(Profile, Platform) 和 TLS/H2 设置,测试的 Python 包中最新 Chrome 为 153。
wreq-js 3.2.0Node.js/Bun,类似 fetch 的 API 及原生 Rust 绑定,封装库有自己的更新节奏。browser、os 及公开的 TLS/H2 overrides,现成 Chrome 配置最高为 149。
primp 2.0.1Python 同步/异步,基于原生引擎的简单客户端,选择操作系统与浏览器只需少量代码。impersonate / impersonate_os,提供现成 Chrome 153,测试的构造器没有公开的完整 ClientHelloSpec。
got-scraping 4.2.1Node.js ESM,接近 got,项目已宣布停止维护并推荐 impit。生成请求头并设置 TLS 传输参数。在请求头生成器中选择版本,并不会生成对应的完整 ClientHello。
impit 0.14.5Node.js/Python,类似 fetch 的 API 与原生 Rust 核心,适合新编写的请求客户端。浏览器预设,测试的 Node 包包含 Chrome 151,但拒绝 Chrome154。
req/v3 3.61.0Go,提供流式高层 API,可通过公开方法配置 TLS 和 HTTP/2。ImpersonateChrome、SetTLSFingerprint、SetTLSFingerprintSpec 和 H2 设置,内置 ImpersonateChrome 使用 Chrome 120。
httpcloak 1.7.2Go 及封装库,通过 Python 测试,提供现成预设及方便的 JSON 导入/导出。preset、JA3/Akamai、describe_preset 和 load_preset_from_json,最新 Chrome 预设为 152,另行测试了自定义 154 配置。
BlankTrail Proxy 1.3.15独立的 HTTP/SOCKS 代理应用,适用于多种语言及旧版、第三方软件。在客户端层面配置,模拟 HTTPS 传输需要向系统安装证书,或在客户端忽略证书校验。提供现成 TLS/HTTP2/HTTP3 浏览器配置,可选择浏览器与系统,或根据 User-Agent 匹配。配置数据库由产品维护,无需在代码中集成库。

API 简单并不意味着无需维护。如果应用已经使用 requests,换用另一款 Python 客户端通常只需局部修改。跨语言的库可能需要绑定、独立服务或重写传输层。第三方闭源软件往往无法嵌入新库。而更新软件包、原生核心、选定预设和自行设置的请求头,其实是四项不同的工作。

将这些库与真实 Chrome 154 比较

截至 10 月 3 日,测试发行包尚无现成 Chrome154 预设,因此我们选择最新可用配置,或原生支持的自动配置,并设置 User-Agent154。例外是 BlankTrail 的现成 Chrome_154_win、got-scraping 请求头生成器和 CycleTLS 手动配置。直接选择 154 及公开配置能力已 单独测试。下面先展示 JA4/H2 是否相同,再分析这些摘要没有体现的原始差异。

依据首次握手 JA4 和 HTTP/2,将选定配置与 Chrome154 比较。摘要一致不代表所有字段一致,详情见可展开部分。
依据首次握手 JA4 和 HTTP/2,将选定配置与 Chrome154 比较。摘要一致不代表所有字段一致,详情见可展开部分。
各配置的 TLS 与 HTTP/2 测试详情
客户端/所选配置首次握手 JA4HTTP/2尚需检查或修正的项目
curl_cffi / chrome150不一致一致缺少 trust_anchors,签名算法没有参考 Chrome154 的 GREASE。
Go tls-client / Chrome_152 与 Chrome_152_PSK一致一致原始抓包确认已检查的稳定 TLS 字段一致,包括 GREASE、ALPS 和 28 个 trust anchor。通过公开 API 将请求头对齐到 154。普通配置产生四次完整握手,152_PSK 则产生一次完整握手和三次被接受的会话恢复。
Python tls-client / chrome_120不一致一致组集合和 ALPS 编码过旧,缺少 trust_anchors,使用 chrome_154 名称不能得到有效的新配置。
noble-tls / chrome_152_PSK,核心 1.16.0一致一致原始抓包确认已检查的稳定 TLS 字段一致,包括 GREASE、ALPS 和 28 个 trust anchor。通过公开 API 将请求头对齐到 154,并获得三次被接受的会话恢复。没有现成的 154 名称,需固定原生核心版本。
rnet / Chrome137不一致一致signature_algorithms 过旧,缺少 trust_anchors,四次请求中未观察到会话恢复。
wreq Python / Chrome153一致一致trust_anchors 是空列表,User-Agent 为 154,但 sec-ch-ua 仍为 153。
wreq-js / chrome_149不一致一致没有现成 154,公开 overrides 没有可任意指定 trust_anchors 内容的参数。
primp / chrome_153一致一致trust_anchors 为空,signature_algorithms 无 GREASE,ALPS 载荷不同,sec-ch-ua 为 153。响应测试未完整完成。
got-scraping / Chrome154 生成器不一致不一致浏览器请求头并不能复现 Chrome 的 SETTINGS 与 TLS 扩展。
impit / chrome151不一致不一致SETTINGS 缺少 Chrome 的 HeaderTableSize,增加了 MaxFrameSize,重复 TLS 也不同。
req / ImpersonateChrome不一致不一致TLS 预设为 120,另有 SETTINGS_MAX_CONCURRENT_STREAMS=1000。
uTLS HelloChrome_Auto + Go HTTP/2不一致不一致TLS 配置为 133,Go H2 需自行设置,uTLS 不承诺自动配置 HTTP/2。
httpcloak / chrome-latest-windows一致一致原始 Client Hints 对应 152,已检查的稳定 TLS 字段(包括非空 trust anchor 集合)与参考 154 一致。
CycleTLS / 复制 Chrome154 的 JA3 与 H2未建立连接核心返回错误:不支持扩展 51764。
BlankTrail / Chrome_154_win一致一致Client Hints154、已检查的稳定 TLS 字段及恢复握手 JA4 的变化与基准一致。

对照客户端 requests 2.34.2、HTTPX 0.28.1、Node fetch、Go net/http 和使用 Schannel 的系统 curl 8.13.0 也与 Chrome 154 不同。这符合预期:它们用于正确发出 HTTP 请求,并非复现浏览器。即使开启 HTTP/2,HTTPX 仍发送自己的 SETTINGS。支持 HTTP/2 本身不等于与 Chrome 一致。

接下来深入分析指纹,而不只看 JA4 哈希

JA4 相同不保证 ClientHello 相同,哈希并不比较所有扩展载荷。下面是针对 Chrome154 的 TCP/TLS 原始数据汇总分析。

比较项目包括密码套件、组、signature_algorithms、TLS 版本、key_share 的组与长度、扩展集合及稳定载荷,包括 ALPN、ALPS、GREASE 和 trust_anchors。密钥、ECH、ticket 和 binder 中的随机字节不要求逐字节相同,允许的重排按浏览器基准评估。

客户端测试配置TLS 字段重复 TLS一致项/发现的差异
BlankTrailChrome_154_win✓✓TLS: 已检查的 TLS 字段、GREASE、ALPS 和 trust_anchors 一致。
重复连接: PSK 被接受,JA4 变化与基准一致。
Go tls-client152 与 152_PSK✓△TLS: 8 条 ClientHello:已检查字段、ALPS 和 28 个 anchor 一致。
重复连接: 152:0/4,152_PSK:3/4。服务端选择了 PSK,扩展 41 位于最后。
noble-tlsnative1.16.0,152 与 152_PSK✓△TLS: 8 条 ClientHello:已检查字段与 anchor 一致。
重复连接: 152:0/4,152_PSK:3/4。ServerHello 确认接受 PSK。
httpcloaklatest✓✓TLS: 已检查字段及非空 anchor 集合一致。
重复连接: PSK 在测试配置中有效。
wreq PythonChrome153△✓TLS: JA4 一致,但 trust_anchors 为空列表 0000。签名算法与 ALPS 一致。
重复连接: PSK 有效,但空 TLS 载荷仍是差异。
primpchrome_153✕✕TLS: trust_anchors 为空,signature_algorithms 无 GREASE,ALPS 载荷不同。
重复连接: 未获得所需 PSK 变化。
curl_cffichrome150✕✕TLS: 缺少 trust_anchors,以及参考 154 签名算法中的 GREASE。
重复连接: 未复现所需 TCP 变化。
Python tls-clientchrome_120✕△TLS: 组与 ALPS 编码过旧,缺少 trust_anchors。chrome_154 名称不能创建新配置。
重复连接: 部分符合,旧 TLS 配置的差异仍存在。
rnetChrome137✕△TLS: signature_algorithms 过旧,缺少 trust_anchors。
重复连接: 初始序列为 0/4,综合评估为部分符合。
wreq-jschrome_149✕△TLS: 配置过旧,overrides 无法设置 anchor 载荷。
重复连接: 部分符合,完整目标序列尚未确认。
req/v3ImpersonateChrome✕✕TLS: 内置 TLS 配置 120 与 154 不一致。
重复连接: 未获得 Chromium 所需的 PSK 变化。
uTLS + Go HTTP/2自身传输实现✕△TLS: HelloChrome_Auto 使用配置 133,可自定义 anchor,但未获得现成 154。
重复连接: 部分符合,需单独配置。
impitchrome151✕✕TLS: TLS 配置 151 及重复握手不同。
重复连接: 重复连接指纹不同。
CycleTLSJA3 + H2 Chrome154✕✕TLS: Chrome154 JA3:报错,不支持扩展 51764。
重复连接: 此模式无成功序列,Safari 另行测试。
got-scraping请求头 154✕✕TLS: 使用自身 TLS 实现及浏览器请求头。
重复连接: 未复现浏览器的指纹变化。
对照:HTTPX、Go net/http、Windows curl、requests、Node fetch自身传输实现✕△TLS: 使用自身 ClientHello,无现成 Chrome154 模拟。
重复连接: 启用缓存的 Go 和 Node:PSK 被接受,但 TLS 不属于浏览器。其余未获得所需变化。

✓:测试配置中一致,✕:未获得目标结果,△:部分符合或取决于配置。TLS 字段以 Chrome154 为基准评估。仅 PSK 被接受,不代表完整重复连接指纹一致。Go tls-client 和 noble-tls 的结果取决于普通配置或 PSK 配置的选择。

JA4 没有体现的关键差异: wreq/primp 的 trust_anchors 包含 0000,而基准与匹配客户端有 28 个 ID,连同列表长度共 186 字节。primp 的 ALPS 为 000403c9bb32,而非基准中的 0003026832 ,包含 h2。anchor 数量仅对应此次抓包,Chrome Root Store 可独立于浏览器版本更新。

请求头另行检查:wreq/primp 将 User-Agent154 与 Client Hints153 组合使用。公开 API 可将两者对齐,但不能修复空 TLS 载荷。

不修改库本身,能否切换到新版浏览器?

没有名为 Chrome154 的预设,并不等于无法复现其行为。我们测试了直接指定配置名称、可用公开参数和若干手动配置。

  • curl_cffi: impersonate="chrome154" 被拒绝。将基准 JA3 和 Akamai 值与 chrome150 一起传入,虽能完成请求,但线上仍是旧配置的 JA4,且没有 trust_anchors。配置被接受并不意味着被完整应用。
  • Python tls-client: 字符串 chrome_154 未产生正确的 154 配置,尽管创建 Session 时未提示配置不存在。因此应检查线上数据,而不只是构造器是否成功。
  • Go tls-client / noble-tls: 没有现成 154 名称,但原始抓包确认配置 152 中已检查的稳定 TLS 字段与基准 154 一致,测得的 H2 也一致。152_PSK 变体复现了会话恢复,原生请求头设置使 HTTP 层与 154 对齐。这一结果无需修改核心源码。自定义 ClientProfile/API 可扩展配置,但此次测试不能证明其能复现所有未来版本。
  • wreq / primp / rnet: 直接选择 154 被拒绝或枚举中没有此项。旧预设配上新 User-Agent 不能实现完整匹配。公开设置可改变部分行为,但是否能填充缺失的特定扩展需另外验证,primp 没有公开的完整 ClientHello 构造器。
  • wreq-js / impit: 未知 Chrome154 会报错。wreq-js 有 TLS/H2 设置,但测试 API 无法任意指定 trust_anchors 载荷。impit 的现成配置取自原生目录。
  • CycleTLS: 支持手动 JA3/JA4R 和 H2,但此次 Chrome154 尝试因不支持扩展 51764 而终止。在这里,仅一条指纹字符串无法构造所需 ClientHello。
  • uTLS / req: 公开的 ClientHelloSpec 和 GenericExtension 允许手动定义扩展,req 则提供 HTTP/2 配置。这是无需修改库的原生路径,但开发者必须维护自定义配置、协调请求头并验证会话恢复。本研究不将这组库完整手动实现 Chrome154 的能力当作已测得结果。
  • got-scraping: 请求头生成器接受版本 154 限制,但测得 TLS/H2 仍不同。要实现当前浏览器传输,光设置生成器还不够。
  • httpcloak: 没有现成的 chrome-154 配置。我们通过 describe_preset 导出 latest 配置,再用 load_preset_from_json 注册请求头已对齐到 154 的自定义 JSON,发出四次请求。首次及恢复握手 JA4、H2 和已检查 TLS 字段一致,这是无需重写库即可配置成功的已验证实例。

因此,部分库确实允许自行组装当前配置。与开箱即用产品的区别,在于谁负责采集基准、验证字段、协调 HTTP 层和持续更新。

TLS resumption:检查会话恢复行为

服务器可发出 session ticket,之后客户端建立新连接并尝试恢复 TLS 会话。在 TLS1.3 中,这会改变 ClientHello:出现带有真实 binder 的 pre_shared_key,且必须位于扩展列表最后。其他扩展也可能移除。每次连接重复同一个“首次握手”模板,并不等于复现浏览器会话行为。机制说明见 RFC 8446, pre_shared_key.

参考 Chrome154 的首次握手 JA4 为 t13d1517h2_8daaf6152771_cb7bf5808d99,恢复时为 t13d1518h2_8daaf6152771_e2d80978ab2e。增加扩展 41,基础 HTTP/2 摘要保持不变。BlankTrail 产生一次首次请求和三次被接受的恢复请求,呈现此变化。Go tls-client152_PSK、使用该核心的 noble-tls、wreq Chrome153、primp 已获得的记录及 httpcloak,也在摘要值上呈现相同变化。

我们的测试中,普通 Go tls-client Chrome_152 未使用 PSK 配置时产生四次首次握手。这不意味着核心无法恢复会话,切换到原生支持的 Chrome_152_PSK 后结果改变。能力与特定模式的配置应分别评估。

Chrome154 与 Firefox147 的首次及恢复 TLS,以及 curl_cffi 重复 ClientHello 的差异。
Chrome154 与 Firefox147 的首次及恢复 TLS,以及 curl_cffi 重复 ClientHello 的差异。

Firefox 的差异更细微。参考 Firefox147 恢复时增加 41,并移除 session_ticket35,JA4 计入的扩展数仍为 17,首次握手后缀 3cbfd9057e0d 变为 e6dcd7ae0a9e。curl_cffi firefox147 保留 35 并增加 41,得到 18 个扩展及后缀 5dff20295fdc。尽管首次指纹正确,重复连接仍与所用基准不同。BlankTrail Firefox147 复现了增加 41、移除 35 的行为。

短测试中未恢复会话,可能取决于 ticket 策略、设置及缓存。因此我们在可比条件下检查服务端是否接受 PSK,而不只是扩展 41 是否存在。

看看这些库如何处理 HTTP/3

HTTP/3 基于 QUIC/UDP,与 TLS/H2 分开测试,包括从 Initial 重建完整 ClientHello、transport parameters、Initial/CID、SETTINGS、QPACK 及请求头顺序。测试涵盖零和非零 QPACK capacity、新连接、PSK 与早期 HTTP 请求,各配置注明字节分析的完整程度。

基准包括 Windows 上已安装的 Chrome154、Edge154.0.4258.48 和 Firefox156.0.1、MacBook 上的 Safari26.6.2,以及真实 Android 和 iPhone 设备抓包。 

真实浏览器首次 QUIC JA4基准中的关键细节
Chrome154q13d0312h3_55b375c5d22e_178839b6cec1存在 trust_anchors,Initial1250 字节,DCID8 / SCID0。
Edge154q13d0311h3_55b375c5d22e_653d80c3fe9d无 trust_anchors,Initial1250,DCID8 / SCID0。修改请求头不会让 Chrome 变成 Edge。
Firefox156q13d0315h3_55b375c5d22e_bb76f32061e3使用自己的 TLS 和 QUIC 参数集合,Initial1252,DCID8 / SCID3。
Safari 26.6.2 macOSq13d0311h3_55b375c5d22e_f2a83c8e78aeInitial1200,DCID8 / SCID0,H3 SETTINGS:QPACK capacity16383、blocked streams100 及 GREASE。

我们归一化了随机 GREASE 值、密钥数据和连接 ID。trust_anchors 比较标识符,而非随机顺序,因为 Root Store 可独立于浏览器版本更新。此 Chrome QUIC 基准没有其 TCP ClientHello 中 signature_algorithms 的 GREASE,不能将一种协议的规则直接套到另一种协议。

HTTP3 协议支持与浏览器指纹准确度是两项不同检查,结果仅对应所测配置。
HTTP3 协议支持与浏览器指纹准确度是两项不同检查,结果仅对应所测配置。

阅读说明: ✓:满足所列标准,✕:存在差异或未达到目标,△:部分结果或确认范围有限。TLS、TP、Initial/CID、SETTINGS 和 QPACK 按所列配置与 Chrome154 比较,其他浏览器配置的差异列在右侧。如 H3 无法工作,其余 ✕ 表示未获得结果,并非每个字段都测出了缺陷。对于拒绝 0-RTT,△ 表示未尝试早期数据便获得响应,因此未确认恢复能力。

方案/模式H3 可用TLS 字段QUIC TPInitial / CIDSETTINGSQPACK0-RTT 中的 HTTP拒绝 0-RTT缺陷与测试结论
curl_cffi
V3ONLY / chrome150
✓✕△✕✓△✕△无 trust_anchors,Initial1200 而非 1250,无早期 HTTP。Edge101、Firefox147 和 Safari260 的原始字段也与目标版本不同。
Go tls-client
protocol racing / 152_PSK
✓✕✕✕✕✕✕✓多余 TLS 扩展、Initial1280、不同 CID,SETTINGS 仅 51=1,QPACK 对 ?0 编码不同。请求分布为 1+3 而非 2+2,HTTP 不是早期请求。144_PSK 改善了 SETTINGS,但未修复完整指纹。
noble-tls
native1.16.0 / 152_PSK
✓✕✕✕✕△✕✓ClientHello、CID 和 SETTINGS 不同,QPACK 尚未单独完整确认。protocol racing 在 H2/H3 上重复发送首个 GET,HTTP 不是早期请求。
httpcloak
http_version=h3 / latest
✓✓✓✓✓△✕✕已检查的 Chrome TLS/TP/Initial/SETTINGS 未发现缺陷,完整 QPACK 准确性尚未证实。q/qd 空闲后及拒绝 0-RTT 时出错。Firefox 不同,Safari iOS 的确认范围受对应基准限制。
impit
forceHttp3 / chrome151
✓✕△✕✕△✕△密码套件/扩展不同,Initial1200、CID20/8,SETTINGS 包含 MAX_FIELD_SECTION_SIZE=2⁶²−1。PSK 有效,但无早期 HTTP。Firefox144 及使用 Edge UA 的 Chrome 也未复现目标。
CycleTLS
forceHTTP3 / custom JA3
✓✕△✕△△✕△JA3 不能复现 QUIC,扩展、组、签名不同,Initial1280,CID 也不同。每次 GET 都建立新的首次握手连接,无 PSK/0-RTT。
req/v3
EnableForceHTTP3
✓✕△△✕△✕△TLS 组/签名不同,有扩展 50,SETTINGS6=10485760。服务器关闭后建立无 PSK 的新连接,无早期 HTTP。
wreq Python
HTTP_3
✕✕✕✕✕✕✕✕H3 未建立:NO_APPLICATION_PROTOCOL。没有可用于比较的成功 HTTP/3 指纹。
rnet
HTTP_3
✕✕✕✕✕✕✕✕H3 未建立:UserUnsupportedVersion。
wreq-js, primp, Python tls-client, HTTPX, requests, Node fetch, got-scraping
测试的软件包/API
✕✕✕✕✕✕✕✕测试配置无可用 QUIC,请求仍使用 TCP/H2 或 H1。
uTLS + Go HTTP/2, Go net/http
测试的传输实现
✕✕✕✕✕✕✕✕TCP 传输实现,H3 需要其他 QUIC/HTTP3 客户端。
Windows curl
Schannel / --http3-only
✕✕✕✕✕✕✕✕此构建不支持 HTTP/3,拒绝相应选项。curl_cffi 不属于此情况。
BlankTrail Proxy
1.3.15 / 六个配置
✓✓✓✓✓✓✓✓已检查字段及场景未发现缺陷。主序列包含 342 个 QUIC 连接,本轮行为测试有 72 次成功请求和 36 个连接。已确认 QPACK/GREASE 与早期 HTTP,并在 Chrome 上实际测试拒绝 0-RTT。

深入分析 HTTP/3 原始字节

ClientHello 由 QUIC Initial 中全部 CRYPTO 片段组装。库的字节级样本包含 25 个连接和 54 个请求头块,保存了 TP 顺序、窗口、流限制、Initial 和 CID。

SETTINGS 在转换为 map 前保存,QPACK 在解码为名称/值对前保存,以保留普通 JSON 日志可能隐藏的真实顺序与编码方式。

✓:已检查字段与所列基准一致,✕:发现差异,△:确认有限,不计为完整匹配。标记仅对应具体配置与样本。下列值中的 max 表示 2⁶²−1.

配置基准TLS 字段QUIC TPInitial / CIDSETTINGSQPACK具体差异与结论
curl_cffi / Chrome150Chrome154✕△✕✓△无 trust_anchors51764,Initial1200 而非 1250。稳定 SETTINGS 及顺序一致,完整 QPACK 准确性尚未确认。
curl_cffi / Safari260Safari 26.6.2 Mac✕△✕✕△groups、key_share 和 supported_versions 不同。CID20/20 而非 8/0,SETTINGS6=max →1=0 →7=0,而非 QPACK capacity16383 和 blocked streams100。
curl_cffi / Edge101Edge154✕△△✕△TLS 不同,SETTINGS6=max →1=0 →7=0。旧预设未复现当前目标。
curl_cffi / Firefox147Firefox156✕✕△△△密码套件、组与 QUIC 参数不同,其余字段未获完整确认。
Go tls-client / 152_PSKChrome154✕✕✕✕✕TLS 扩展类似 TCP,Initial1280。SETTINGS 仅 51=1,而非 1/6/7/51 加 GREASE。QPACK 对 ?0 使用不同 Huffman 标志。
Go tls-client / 144_PSKChrome154✕△△✓✕SETTINGS 及顺序一致,但 TLS/QUIC154 不一致。QPACK 对 ?0 使用不同 Huffman 标志,旧预设仅修复部分字段。
noble-tls / native1.16.0Chrome154 / Safari26✕△✕✕△ClientHello、CID 和 SETTINGS 不同。封装库的完整 QPACK 未单独确认,不能直接套用 Go 的结果。
httpcloak / Firefox-latestFirefox156✕✕△△△TLS 不同,TP 窗口 4=15728640、5/6/7=6291456,而非 25165824、12582912、1048576、1048576。
httpcloak / Chrome-latestChrome154✓✓✓✓△已检查的 TLS 字段、TP 集合、Initial/CID 和 SETTINGS 未发现缺陷。完整 QPACK 准确性未确认,行为错误见 H3 总表。
httpcloak / Safari iOS有限的 Mac 基准△△△△△QUIC 窗口与测得的 macOS Safari 不同。此次字节样本没有独立 iPhone 基准,因此并非已证实的 iPhone 配置缺陷。
impit / Chrome151Chrome154✕✕✕✕△15 个密码套件而非 3 个 TLS1.3 套件,TP4=max、5/6/7=1250000,而非 15728640 和 6291456。Initial1200,SETTINGS 不同。
CycleTLS / Chrome154 JA3Chrome154✕✕✕△△ClientHello 不同,TP4=1048576、5/6/7=524288,而非 15728640 和 6291456。Initial1280,自定义 JA3 未成为精确 QUIC 配置。
req/v3 / ForceHTTP3Chrome154✕✕△✕△TLS 不同,包括扩展 50。TP4=786432,streams_bidi8=0 而非 100。SETTINGS 仅 6=10485760,而非 262144 及 1/7/51/GREASE。
BlankTrail / 1.3.15六个测试配置✓✓✓✓✓已检查字段未发现缺陷,TLS、归一化 TP、Initial/CID、SETTINGS 和 QPACK 与保存的基准一致。Safari:fresh/PSK/0-RTT、Initial1200,Chromium:encoder stream10。

协议允许的参数也可能与浏览器不同。例如 Initial1200 或不同 QUIC 窗口并非协议错误,但无法复现所选基准。这不证明反欺诈系统必然能检测出来,只说明存在潜在可能。

SETTINGS:一个具体差异
Chrome154 / Edge154: 1=65536 → 6=262144 → 7=100 → 51=1 → GREASE
Go tls-client / 152_PSK: 51=1
req/v3 / ForceHTTP3: 6=10485760

152_PSK 缺失参数无法用 GREASE 随机排序解释。ID/value 对及其顺序在转换为 map 前比较。格式说明见 RFC9114,自行抓包方法见 下文.

QPACK:相同请求头也可能以不同方式编码

真实 Chrome154 和 Edge154 的头字段 sec-ch-ua-mobile: ?0 发送时不对值进行 Huffman 编码,而 Go tls-client152_PSK 和 144_PSK 使用了该编码。两者均合法,但字节与基准不同。

此类比较要求请求头值与请求上下文相同。curl_cffi 的 platform 差异不计为缺陷,因为比较的是 macOS 与 Windows。原始 54 个 QPACK 块在 capacity0 下采集,动态表及 encoder/decoder streams 在非零 capacity 下单独测试,依据 RFC9204.

HTTP/3 行为通过同一会话内四次 GET 测试,间隔 2、42 和 2 秒,并分别自动选择及强制使用 H3: q/qd - 无 0-RTT,QPACK capacity0/65536, qz - 允许 0-RTT。

PSK、被接受的 0-RTT 和早期 HTTP 请求是三种不同结果。 pre_shared_key 扩展只是提出恢复会话。服务端分别确认 PSK 与早期数据是否被接受,还需另外检查承载 GET 本身的流是否在 0-RTT 中打开。Go tls-client 和 noble-tls 的早期数据被服务端接受,但 GET 在握手后才发出,因此仅 used_0rtt 标志不够。

客户端连接选择与生命周期0-RTT 中的 HTTP拒绝 0-RTT结果与局限
BlankTrail ProxyChrome/Edge:立即 H3,2+2 次请求;Firefox:先 TCP。空闲后使用 PSK。✓✓六个配置均发送早期 HTTP。72 次请求无错误,36 个 QUIC 连接的已检查原始字段无差异。
curl_cffiV3 模式立即 H3,2+2 次请求,空闲后 PSK。✕△测试的 Chrome150 配置未提出早期数据,与 154 的原始差异仍存在。
Go tls-client立即 H3,1+3 次请求:第二次 GET 已建立新的恢复连接,之后连接跨空闲期保留。✕✓服务端接受 0-RTT,但 HTTP 请求并非早期请求。原始 TLS/QUIC 和 SETTINGS 不同。
noble-tls同样为 1+3 的 H3 序列,但首个 GET 还通过 H2 发送。✕✓protocol_racing=True 时,三种模式的首个 GET 均在 H2 与 H3 重复发送。无早期 HTTP,原始 QUIC 差异仍存在。
httpcloakauto:所有请求走 TCP。强制 H3:q/qd 空闲后出错,qz 为 2+2。✕✕24 次普通尝试中 4 次错误。拒绝 0-RTT 时出错,原生两次重试仍未解决。
impithttp3=True 时立即 H3,2+2 次请求,空闲后 PSK。✕△未提出早期数据,与所选浏览器的原始差异仍存在。
req/v3auto:首个请求 TCP,之后 H3。强制模式:同一 H3 连接跨空闲期保留。✕△服务端强制关闭后,新连接仍为首次握手,测试配置未获得 PSK/0-RTT。
CycleTLSauto:TCP。强制 H3:四次请求每次都建立新连接。✕△无 PSK 或早期数据。请求成功,但连接复用与原始字段不同于 Chrome/Edge。

“拒绝 0-RTT”列中,✓ 表示早期数据尝试被拒后请求成功送达,✕ 表示错误,△ 表示未尝试 0-RTT 就成功请求,因此未测试该客户端的恢复机制。服务端保留 ticket key 与 PSK 能力,关闭原连接但禁止早期数据。BlankTrail、Go tls-client 和 noble-tls 在恢复连接上获得响应,但 0-RTT 未被接受。httpcloak 报错 0-RTT rejected,下一次请求报错 tls: illegal parameter。原生 retry=2 也未恢复请求。

noble-tls 存在重复 GET。 三种自动模式中,服务端都在 HTTP/2 和 HTTP/3 上处理同一个首个 URL,计划四次请求,实际收到五次。直接 Go tls-client 在此序列没有重复。结果仅针对 GET 与 protocol_racing=True,此实验未测试 POST。

相同四请求场景下的 HTTP/3 连接生命周期,完整条件与局限见表格。
相同四请求场景下的 HTTP/3 连接生命周期,完整条件与局限见表格。

相同 fetch 场景中,真实 Chrome 和 Edge 先发送两次首次 H3 请求,空闲后在新的恢复连接上再发两次,qz 中第一条为早期请求。BlankTrail 对应配置复现了此序列。Safari 与 Firefox 的初始传输选择取决于已保存连接及 origin 合并:Safari 在 q 中保持 TCP,qd/qz 中使用 H3。因此首个请求走 TCP,不能一概视为所有浏览器配置的缺陷。

本轮 BlankTrail 测试了 Chrome154 Windows/Android、Edge154、Firefox156 和 Safari26 macOS/iPhone。72 次请求全部完成,36 个 QUIC 连接中已检查的稳定 TLS 字段、transport parameters、Initial/CID、SETTINGS、控制流和 QPACK 均一致。六个配置都在 qz 中发送早期 HTTP。测试及拒绝 0-RTT 实验使用 1.4.1064 构建,其修改计划进入 1.3.15 发布版。这仅确认具体场景,并非所有排列的频率统计或任意网络状态下的行为。

Edge 与 Firefox:检验当前目标,而非预设名称

HTTP/2 场景使用可用配置请求 Edge154 和 Firefox156。curl_cffi edge101 与 rnet Edge134 的 TLS 不同于 Edge154,wreq-js Edge148 不是现成 154。primp Edge151 的简要检测一致,但原始签名和 ALPS 不同。httpcloak 的 Chrome 配置即使搭配正确 Edge 请求头,仍保留多余 trust_anchors。库中的 Firefox147/148/151 不算完整匹配 156,原始比较显示密码套件/组不同。简要 JSON 没有报错不能消除该差异。

进一步检查 Safari、iOS 和 Android 配置质量

移动 User-Agent 不能代替移动传输实现。比较涵盖 Safari26 macOS/iPhone 和 Chrome154 Android,而不只看预设名称。

客户端Safari macOSSafari iPhoneChrome AndroidSafari:结果与差异Android:结果与差异
curl_cffi✕✕✕safari260 / safari260_ios:HTTP/2 一致,TLS 不同。iOS 预设包含 session_ticket35 和 padding21,所用首次握手基准没有这两项。chrome131_android:TLS 类型过旧,未匹配目标 154。
wreq Python△△△Safari26 和 SafariIos26:首次 JA4/H2 一致,每个预设四次请求均未观察到被接受的会话恢复。Chrome153 + Platform.Android:JA4/H2 与 154 类型一致,但 trust_anchors 为空,Client Hints 仍为 153。
wreq-js△△✕safari_26 / safari_ios_26:首次 JA4/H2 一致,标准预设未恢复会话。另行尝试通过公开 overrides 启用 PSK,也未匹配参考配置。chrome_149 + android:HTTP/2 一致,首次 TLS 不同。
primp△△△safari_26 + macos/ios:已获得记录的 JA4/H2 一致,观察到恢复,但原始 ClientHello 的 GREASE 是否存在、顺序及部分字段内容不同,响应不完整。chrome_153 + android:摘要一致,但稳定 TLS 字段及 Client Hints 版本仍不同。
Go tls-client 1.16.0✕△△直接 Go API:safari_ios_26_0 的首次 JA4/H2 一致,四次请求无 PSK。宣称 macOS Safari26 的 safari_16_0 在 TLS 与 H2 上不同,测试目录无现成 macOS26。chrome_131 配移动端 154 请求头:TLS 不同,H2 一致。Chrome_152_PSK 配对齐的 Android154 请求头:首次及恢复 JA4/H2 一致,已检查稳定 TLS 字段与所用参考传输类型一致。
noble-tls / native 1.16.0✕△△safari_ios_26_0:首次 JA4/H2 一致,短测试无 PSK。旧 macOS safari_16_0 未匹配目标 26。chrome_131 配移动 UA:首次 TLS 不一致。原生 chrome_152_PSK 配对齐的 Android154 请求头,获得一致的首次/恢复 JA4/H2 及已检查稳定 TLS 字段。
httpcloak✕△△iOS latest 的 TLS 摘要与 Safari26 一致,但 H2 的 SETTINGS 顺序、窗口及伪头字段不同。没有 safari-latest-macos,此测试未确认独立 macOS26 配置。chrome-latest-android:JA4/H2 与 154 类型一致,需更新原始预设 152 的 HTTP 请求头。
impit✕✕✕测试的 Node 包 Browser 枚举没有 Safari。chrome151 配移动 UA:TLS/H2 不同,此测试没有独立 Android 平台参数。
BlankTrail✓✓✓Safari_26_macOS 和 Safari_26_iPhone:TCP/H2 保持无 PSK 的首次 WebKit 指纹。HTTP3 空闲后出现 41,JA4 按 Safari26.6.2 QUIC 基准变化。Chrome_154_and:首次及恢复 JA4/H2 一致,已检查稳定 TLS 字段与所用 Chrome154 类型基准一致。

目标为 Safari26 和 Chrome154 Android。✓:测试配置中一致,✕:未复现目标配置,△:部分一致或需配置。只有 JA4/H2 一致、没有原始字段确认,不标为绿色。Go tls-client 和 noble-tls 的原生手动配置使已检查 Android TCP/TLS 字段一致,但未覆盖全部模拟,包括 HTTP/3。

Safari: 真实 26.6.2 在测试的新 TCP 连接中未使用 PSK,但会恢复 QUIC。因此没有 TCP 恢复不算缺陷,curl_cffi 和 primp 的 Safari 场景出现 PSK,则与测得行为不同。

iOS: BlankTrail 已测试 CriOS/FxiOS/EdgiOS 路径使用 WebKit/Safari 传输,要求其发送桌面 Chromium/Gecko ClientHello 不正确。分类器警告与客户端缺陷分别处理。

Android: 真实设备 Chrome154 确认 PSK、0-RTT 早期 HTTP 和 QPACK encoder stream10。BlankTrail 复现已检查字段与场景,库配置的局限见表。

Safari/iOS/Android、GREASE 与 QPACK 抓包详情

Safari 重复 TCP/H2 连接:所有客户端统一测试

Safari 测试覆盖所有 20 个方案,没有现成配置时使用普通传输搭配 Safari User-Agent。请求间保留客户端与缓存,服务端日志确认新连接。

真实 Safari26.6.2 在 safaridriver 或普通窗口中,连接被强制关闭后均未提出 TCP PSK。同服务器上的 Go 对照客户端成功恢复。因此 Safari 没有 TCP 恢复本身不扣分,需结合首次 TLS/H2 准确度评估。无 PSK 的旧 Safari16 并不会因此变为 Safari26。

客户端/可用 Safari 配置新连接/PSK结论
BlankTrail: Safari 26 macOS / iPhone4+4, PSK0, accepted0重复完整 TLS/H2 握手符合所选 Safari26 类型,确认缺口已补齐。
Go tls-client: iOS26, macOS164+4, PSK0iOS26:首次摘要符合 26,macOS16 仍使用旧 TLS 配置。
noble-tls: iOS26, macOS164+4, PSK0核心结果相同,没有 PSK 并不能修复旧 macOS 预设。
wreq26.4 / wreq-js26.44+4, PSK0首次 Safari 摘要及无 PSK 符合所选行为,但不能消除其他原始数据局限。
httpcloak Safari iOS4, PSK0重复完整握手,测得的 H2 与 Safari 差异仍存在。
rnet Safari18.54, PSK0首次摘要符合 26 类型,预设版本与原始差异仍存在。
curl_cffi Safari2604 个连接,提出/接受 PSK 3 次首次 TLS 已不同,三次重复 ClientHello 恢复了会话,与所选 Safari26.6.2 不同。
primp Safari264 次尝试获得 2 个连接,接受 PSK 1 次重复 ClientHello 包含 41,服务端接受恢复,另两条响应在 H2 关闭时丢失。明确列出未完成测试计数。
Python tls-client Safari15.6.14, PSK0过旧的首次 TLS 不符合 26。
impit, CycleTLS, req/v3, uTLS+GoH2, got-scraping各 4 个响应,未获得精确 Safari26测试的回退/普通传输不能替代缺失的当前 Safari 预设。非浏览器传输中的 PSK 不单独视为 Safari 配置缺陷。
requests, HTTPX, Go net/http, Windows curl, Node fetch各 4 次尝试,HTTPX 获得 2 个响应对照仅设置 Safari User-Agent,既未声明也未实现 Safari 模拟。

iOS:浏览器名称与传输引擎

BlankTrail1.3.15 测试了 database 筛选 chrome+ios、firefox+ios、edge+ios 和 safari+ios,以及按 CriOS、FxiOS、EdgiOS 和 iPad 上 EdgiOS 的 User-Agent 选择配置。八条路径均得到同一 WebKit/Safari 传输类型。UA 品牌与版本不同,并不意味着 iOS 配置应发送桌面 Chromium 或 Gecko ClientHello。

配置选择路径新 TCP 连接测得 TLS/H2PSK41
database chrome+ios / firefox+ios / edge+ios / safari+ios各 3 个,共 12 个Safari JA4 t13d2013h2_a09f3c656075_7f0f34a4126d, H2 m,s,a,p12 个中均没有
按 UA:CriOS / FxiOS / EdgiOS / EdgiOS iPad各 3 个,共 12 个相同 Safari JA4 与 H212 个中均没有
Chrome Windows 对照3Fresh t13d1517h2…cb7bf5808d99 → PSK t13d1518h2…e2d80978ab2e, Chromium H2 m,a,s,p两条重复 ClientHello 中存在

八条 iOS 路径的 24 条 TCP 记录均产生 H2 2:0;3:100;4:2097152;9:1|10420225|0|m,s,a,p。UA 包含相应 CriOS/FxiOS/EdgiOS 标记。这测试的是产品配置选择,并非真实 iPhone/iPad 的 24 次运行。

本轮 iOS 测试中,研究版 /client 获得 24 个响应,其中 21 个 CriOS/FxiOS/EdgiOS 响应含 engine_mismatch,CriOS/EdgiOS 还含 client_hints_absent。在公开的 /client 上另测八种场景,七种复现了这些误报,Safari 通过。服务端记录显示预期 WebKit/Safari TLS/H2。在此要求桌面 Chromium/Gecko 和桌面 Client Hints,属于检测器分类错误,并非发现的产品缺陷。

Safari HTTP/3:首次与 PSK 形式分别建立基准

与 TCP 不同,保存的 Safari26.6.2 QUIC 基准包含首次形式及两种恢复变体,分别有、无 0-RTT。BlankTrail 在空闲后保留缓存,复现了这些状态。

场景QUIC JA4扩展Initial
真实 Safari26.6.2:首次握手q13d0311h3_55b375c5d22e_f2a83c8e78ae无 41/421200
真实 Safari:PSK,无 0-RTTq13d0312h3_55b375c5d22e_151122171f7d41 最后,无 421200
真实 Safari:PSK,允许 0-RTTq13d0313h3_55b375c5d22e_6bb9a3ac9a4b42 位于 45 与 43 之间,41 最后1200
BlankTrail Safari 26 macOS / iPhone各配置:fresh…f2a83c8e78ae → PSK…151122171f7d顺序、41 最后及无 42,符合所选基准变体四个 QUIC 连接均为 1200

Safari macOS/iPhone 比较的密码套件、组、签名算法、版本、key_share 形式、稳定扩展载荷及 TP 值,在归一化随机数据后与 QUIC 基准一致。

首次握手线上顺序:

GREASE,0,10,16,5,13,18,51,45,43,57,27,GREASE

无 0-RTT 的 PSK:

GREASE,0,10,16,5,13,18,51,45,43,57,27,GREASE,41



观察到的 transport parameter 顺序:

14 15 4 5 6 7 9

9 14 15 4 5 6 7

4 5 6 7 9 14 15

Safari TP 顺序为 4,5,6,7,9,14,15 的循环旋转,而非任意打乱。产品采集的所有顺序都属于此系列。

Safari macOS 和 iPhone 不仅确认 tls_resumed 与 used_0rtt,还确认早期数据中 HTTP 请求本身的字节。延迟服务端响应测量时,Early-Data:1 位于重复请求最后一个头字段,首次请求没有此项。

本轮 BlankTrail 六个配置的 342 个 QUIC 连接全部通过所列稳定 TLS 字段、TP、SETTINGS、Initial/CID 和 QPACK 流检查。Chromium 在积累 origin RTT 后发送 12583,Firefox 保留固定 0xff02de1a(min_ack_delay),不能将其视为随机 GREASE。

H3 测量条件:

启用 h2_spoofing、enable_http3 和 spoof_headers,明确指定配置,UA 取自目录。原客户端通过 Sec-Fetch-Dest/Mode/Site 传递上下文。

首个 QPACK 块取决于 SETTINGS 到达时间。真实 Chrome154.0.8037.95 的六次对照运行中,首块均为动态,NetLog 确认 SETTINGS 先于头字段。因此产品首块为动态本身不算缺陷。

六个配置的 HTTP/3 结构、GREASE 与 QPACK

随机排序测试包含 300 个首次 HTTP/3 连接,Chrome154 Windows/Android、Edge154、Firefox156 和 Safari26 macOS/iPhone 各 50 个。每个配置 25 个连接使用服务端 QPACK capacity0,另 25 个使用 capacity65536。

检查项目Chrome / EdgeFirefoxSafari macOS / iPhone
稳定 TLS 字段与 SETTINGS100 个连接全部一致50 个连接全部一致100 个连接全部一致,macOS 使用独立基准比较
Initial 与 CID1250/1250, DCID8, SCID01252/1252,DCID 可变,SCID31200/1200, DCID8, SCID0
TP 与 TLS 顺序各 50 种不同 TP 顺序,GREASE 与 QUIC 版本顺序变化TP 固定,TLS 随机排序,末尾为 57,65037三种允许的 TP 旋转均出现,无其他顺序
SETTINGS 后的帧GREASE 载荷 0–3 字节及 PRIORITY_UPDATEGREASE 载荷 0–7 字节,无 PRIORITY_UPDATE无多余帧
capacity0 时的 QPACK静态块,仅控制流静态块、控制流及两个 QPACK 流静态块,仅控制流
capacity65536 时的 QPACK插入、动态引用、encoder stream10插入及两个 QPACK 流编码器发送服务端容量,请求保持静态

Chromium 每个配置产生 50 种不同 TLS 与 TP 顺序,以及两种 available_versions 顺序。Firefox 有 50 种 TLS 顺序,TP 固定;Safari 的 TLS 固定,TP 为三种参考顺序。300 个首次连接全部通过结构检查,PSK 与早期 HTTP 在重复连接中测试。

Edge 与 Firefox 使用保存的 100 和 120 个浏览器连接进行八次双样本 KS 检验,在 0.01 显著性水平下未拒绝各单项分布一致,最小 p=0.029。这不证明联合分布相同。本轮测试检查结构与变化,但未重复这些 KS 计算。

Chrome154 Android:与真实设备比较

真实 Android154 抓包包含 q/qd/qz 的首次与恢复连接:q/qd 接受 PSK,无 0-RTT;qz 接受 PSK 与 0-RTT,并确认早期 HTTP。

Android 与 BlankTrail 的已检查 TLS 字段、归一化 TP、稳定 SETTINGS 和头字段顺序一致。Initial1250/1250、DCID8、SCID0。

场景真实 Android Chrome154BlankTrail1.3.15
qd:动态表控制 stream2,QPACK 编码器 stream10控制 stream2,QPACK 编码器 stream10,一致
qz:静态形式仅控制 stream2仅控制 stream2,一致
qz:空闲后重复请求PSK/0-RTT 被接受,请求在 0-RTT 中PSK/0-RTT 被接受,请求在 0-RTT 中,一致

真实桌面 Chrome 和 Android 确认 Chromium encoder stream10。BlankTrail 在 Chrome Windows、Edge Windows 和 Chrome Android 每个配置的 25 个首次动态表连接及重复连接中复现了该流。

BlankTrail:为旧版与第三方软件提供浏览器传输

Linux curl7.74.0 通过 BlankTrail 获得已检查的 Chrome154、Edge154、Firefox156 和 Safari26 配置。旧客户端无需改变,所选 TLS/H2/H3 传输由代理构建。

实测场景:旧 curl 通过 BlankTrail 获得所选浏览器 TLS/H2 传输。
实测场景:旧 curl 通过 BlankTrail 获得所选浏览器 TLS/H2 传输。

优点: 无需源码或集成原生库,即可连接不同技术栈与第三方软件。 缺点: 需另行安装、运行和维护应用。HTTPS 模拟要求客户端信任 CA,证书固定可能妨碍使用。

文章采用版本 1.3.15。BlankTrail 声明的规则是稳定浏览器发布后不晚于五天更新数据库。本研究检查目录 841 个配置中列出的样本,而整个目录均使用真实设备和所需操作系统上的对应真实浏览器版本采集并测试。

TCP 实验参数及测得 JA4/H2

使用 Linux curl7.74.0 与 OpenSSL 测试,同一客户端经 BlankTrail 获得 Chrome154、Edge154、Firefox156、Safari26 及更早配置。每个配置启用新测试端口,TLS 缓存为空。开启 H2 spoofing 与 session resumption,关闭 HTTP/3 和 browser_mode。切换配置后重新测试,不把上一配置的 ticket 用作“首次”连接。

下面是三个 BlankTrail 配置的实测指纹。HTTP/2 按 Akamai 格式记录:发送顺序的 SETTINGS、连接 WINDOW_UPDATE、优先级摘要及伪头字段顺序。符号 m, a, s, p 表示 :method, :authority, :scheme, :path。Chrome/Firefox 在 TLS 恢复后保持 HTTP2,Safari 在重复完整握手后保持。

目录有 841 个配置,实际测试覆盖列出的样本,而非整个目录。

Chrome_154_win

fresh:   t13d1517h2_8daaf6152771_cb7bf5808d99

resumed: t13d1518h2_8daaf6152771_e2d80978ab2e

HTTP/2:  1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p



Firefox_156_win

fresh:   t13d1517h2_8daaf6152771_3cbfd9057e0d

resumed: t13d1517h2_8daaf6152771_e6dcd7ae0a9e

HTTP/2:  1:65536;2:0;4:131072;5:16384|12517377|0|m,p,a,s



Safari_26_macOS

fresh:   t13d2013h2_a09f3c656075_7f0f34a4126d

repeat:  t13d2013h2_a09f3c656075_7f0f34a4126d (full handshake; no PSK)

HTTP/2:  2:0;3:100;4:2097152;9:1|10420225|0|m,s,a,p

如何复现比较

  1. 在以下端点采集真实目标浏览器与被测客户端的结果: tls.peet.ws/api/all,保存版本、配置、操作系统与 JSON。
  2. 在以下端点获得简要检测: BlankTrail /client。它有助于发现矛盾,但不能确认所有字节一致。
  3. 比较实际协议、TLS 字段、SETTINGS 与请求头。JA4 一致时,检查扩展载荷,包括 trust_anchors。
  4. 保留会话缓存测试新连接。H3 要分别检查 PSK、被接受的 0-RTT 与 HTTP 请求本身是否提前发送。
详细步骤:pcap、会话密钥、QPACK 及拒绝 0-RTT 测试

BlankTrail /client 提供简要结果:识别出的常用客户端、声明的浏览器及发现的矛盾。保存 JSON、客户端版本、预设、系统和日期。这是方便的第一步,没有 findings 并不证明所有字节一致。

  1. 获取独立的详细结果。 打开 tls.peet.ws/api/all ,先用真实目标浏览器,再用库请求同一 URL,保存两个 JSON。服务说明见 TrackMe 仓库,/api/all 返回采集的 TLS 与 HTTP 字段。比较浏览器导航与库 fetch 时,必须考虑 HTTP 请求头上下文差异。
  2. 从传输层开始。 检查 http_version 与协商的 ALPN。TLS 比较 ciphers、extensions、supported_versions、supported_groups、signature_algorithms、key_share、ALPS 和 compression。JA3/JA4/PeetPrint 用作摘要,哈希一致时另查扩展内容,包括 trust_anchors。HTTP2 比较 akamai_fingerprint 和 sent_frames:SETTINGS、WINDOW_UPDATE、伪头字段和普通头字段。可用字段取决于实际协议。
  3. 不要把正常随机性视为缺陷。 归一化 GREASE 值,但保留数量与位置。Chrome/Edge 应采集多个新连接检查随机排序。random、session ID、key_share 密钥字节、ticket 和 binder 不应重复。比较密钥组与长度,trust_anchors 按 Root Store 版本允许的 ID 集合比较。基准中固定的顺序单独检查。
  4. 要分析真正的原始字节,请自行抓包。 /api/all 提供解析字段,并非每次请求的完整 pcap。用 Wireshark 捕获客户端 TCP443 和 UDP443。TCP ClientHello 根据 TLS record 与 handshake 解析,QUIC ClientHello 必须从 Initial 的 CRYPTO 片段重建,不能将单个 UDP 包视为完整 TLS。HTTP2/HTTP3 需要会话密钥:在支持的客户端启用 key log,再于 Wireshark TLS 设置指定文件。步骤见 Wireshark TLS 文档,QUIC 字段见 dissector 参考。公开 JSON 不能代替此步骤。
  5. 在同一会话中分别测试首次及新建连接。 保留客户端会话缓存,等待 ticket,由自己的服务器关闭连接,同时保留 ticket key。旧 H2/H3 上的新请求不算恢复。ClientHello 中 PSK41 只是提出恢复,需通过 ServerHello 所选 PSK identity 或服务端 DidResume 确认接受。Safari26.6.2 要区分 TCP/H2 与 QUIC/H3。所选 TCP 实验中新连接没有 41,QUIC 基准会恢复,无 0-RTT 时仅增加 41,允许 0-RTT 时还增加 42。应比较对应协议与服务端策略。
  6. 单独测试 HTTP3。 启用原生 H3 模式,使用 Alt-Svc/HTTPS record 宣告,并确认响应确实走 H3。独立公开分析可尝试 tls3.peet.ws/api/all,但 URL 本身不保证 QUIC,需检查实际 http_version。pcap 中比较 TLS、完整 transport parameter 载荷、首个 Initial 大小、CID、SETTINGS 和头字段顺序。解密后,在转换为 map 前保存 SETTINGS type4,分别比较 ID/value 顺序与 GREASE。HEADERS type1 先解析 QPACK 前缀与指令,再比较解码值;值相同时,比较 static indices、literal/name-reference 和 Huffman/Never Index。QPACK 动态需用非零服务端 capacity、多次请求及 encoder/decoder streams 单独测试。不能自动将 TCP GREASE 规则用于 QUIC。
  7. 按连接测量 HTTP/3 行为。 同一客户端发送四次安全 GET,间隔 2、42 和 2 秒。在自有服务器保存每次请求的 connection ID、协议、stream ID 与时间。分别使用 capacity0/65536,以及允许/禁止 0-RTT 重复测试。拒绝早期数据时保留 ticket key 与 PSK,但禁止 early data,确认握手后请求只送达一次。分别记录 early_data 提议、服务端接受及 HTTP 流是否在 0-RTT 中打开。公开 /client 只提供简要检测,此类时间序列需带会话密钥的 pcap 或自有 HTTP/3 服务日志。

curl_cffi 示例:首个 URL 提供详细字段,第二个提供简要检测。这里选择可用 chrome150,chrome 名称不保证支持 154。

from curl_cffi import requests

with requests.Session(impersonate="chrome150") as session:

    for url in ("https://tls.peet.ws/api/all",

                "https://audit.blanktrail.com/client"):

        response = session.get(url, timeout=20)

        print(response.json())

旧客户端经 BlankTrail 使用时,设置所需配置的端口及对应 CA,并分别比较 H2 与 H3。示例:

curl --proxy http://127.0.0.1:PROXY_PORT \

  --cacert /path/to/blanktrail-ca.crt \

  https://tls.peet.ws/api/all
匿名化真实检测器响应的静态视图:requests、wreq 和 BlankTrail,响应来自 TCP 检查。
匿名化真实检测器响应的静态视图:requests、wreq 和 BlankTrail,响应来自 TCP 检查。

图中保留真实 TCP 检查的简要 /client 响应,去除 IP 与一次性名称。绿色结果只针对 TCP,并不确认 HTTP/3 一致。

哪些方案表现更强

BlankTrail 在已测试的当前目标覆盖及现成配置方面排名第一。 库中,httpcloak 已检查原始字段最接近 Chrome QUIC,但空闲后及拒绝 0-RTT 时出错。Go tls-client 与 noble-tls 准确复现已测试 Chrome TCP/H2,但有 QUIC/QPACK 局限,noble-tls 还存在重复 GET。wreq/primp 的相同 JA4 隐藏了空 trust_anchors,其他客户端旧预设仍有列出的 TLS/H2/H3 缺陷。

排名考虑目标配置准确度、浏览器覆盖、HTTP/3 与维护便利性。这是测试配置排名,并非反欺诈检测概率。

结果确认范围

确认范围与 iOS 分类

当前 Firefox156 保存的原始 TCP 基准是首次握手。产品恢复时增加 41、移除 35,但尚无完整配对的 Firefox156 恢复握手抓包,因此既不将该变化称为已证实缺陷,也不视为完整原始基准比较。Safari TCP 已确认密码套件、扩展、签名算法、H2 与无 PSK,但并非每个扩展载荷都有保存的配对浏览器基准。Edge 四次 qz 重复均接受 QUIC0-RTT,其中两次有早期 HTTP。接受 0-RTT 不代表每个 HTTP 请求都在握手结束前发送,比较频率需要可比的真实 Edge 序列。

20 个客户端排名

优先级:Chrome154 准确度,其次 Safari/Firefox/Edge/Android 与 HTTP/3,最后现成配置与集成。✓:标准已确认,△:部分或有限,✕:功能不存在或未达目标。说明见悬浮提示与客户端卡片。Chrome 绿色仅指 TCP/H2,HTTP/3 单独评估。

指纹测试结果

№客户端Chrome154Safari26Firefox156Edge154Android154HTTP/3HTTP/2trust_anchorsClient HintsGREASE重复 TLS
1BlankTrail Proxy✓✓✓✓✓✓✓✓✓✓✓
2httpcloak✓△✕✕△△△✓△△✓
3Go tls-client✓△✕✕△✕△✓△△△
4noble-tls✓△✕✕△✕△✓△△△
5wreq Python△△✕✕△✕✓✕✕△✓
6primp△△✕✕△✕✓✕✕✕✕
7wreq-js✕△✕✕✕✕✓✕✕△△
8curl_cffi / curl-impersonate✕✕✕✕✕✕✓✕△✕✕
9rnet✕△✕✕✕✕✓✕✕✕△
10Python tls-client✕✕✕✕✕✕✓✕△✕△
11req/v3✕✕✕✕✕✕△✕△✕✕
12uTLS + Go HTTP/2✕✕✕✕✕✕✕✓△△△
13impit✕✕✕✕✕✕✕✕△✕✕
14CycleTLS✕△✕✕✕✕△✕△✕△
15got-scraping✕✕✕✕✕✕✕✕✓✕✕
16HTTPX✕✕✕✕✕✕△✕△✕✕
17Go net/http✕✕✕✕✕✕△✕△✕△
18Windows curl✕✕✕✕✕✕✕✕△✕✕
19requests✕✕✕✕✕✕✕✕△✕✕
20Node fetch✕✕✕✕✕✕✕✕△✕△

集成、配置与维护

№客户端集成配置更新技术栈
1BlankTrail Proxy✓✓✓✓
2httpcloak△△△△
3Go tls-client△△△△
4noble-tls✓△△△
5wreq Python✓✕△△
6primp✓✕△△
7wreq-js✓✕△△
8curl_cffi / curl-impersonate✓✕△△
9rnet✓✕△△
10Python tls-client✓✕△△
11req/v3△△△△
12uTLS + Go HTTP/2✕△✕△
13impit✓✕△△
14CycleTLS△△✕△
15got-scraping✓✕✕△
16HTTPX✓✕✕△
17Go net/http✓✕✕△
18Windows curl✓✕✕△
19requests✓✕✕△
20Node fetch✓✕✕△

各客户端的优势、局限与结论

展开卡片查看版本、所选配置及各项评分说明,两张表的客户端顺序与排名一致。

1. BlankTrail Proxy 1.3.15

优势: 现成配置覆盖当前目标,无需修改代码即可通过代理连接旧版/第三方软件,已测 Android H3 与 Chromium QPACK 字段符合基准

弱点/局限: 独立应用需要另行安装,但跨平台支持及 Docker 部署可弥补这一点。

结论: 凭现成配置覆盖当前目标及代理兼容第三方软件排名第一。已测 H3/QPACK 字段符合基准,仍需单独安装,并保留已注明的确认范围。HTTP/3:72 次请求无错误,36 个连接的已检查字段无差异,已测试早期 GET 及拒绝 0-RTT。

✓ Chrome154
H2:154 字段
✓ Safari26 mac/iOS
TCP Safari26 与 database/UA CriOS/FxiOS/EdgiOS:WebKit H2,24 个 iOS 连接无 PSK
✓ Firefox156
Firefox156 首次 TCP/H2 与已检查 H3 字段一致,无完整配对的 156 恢复 TCP 原始基准
✓ Edge154
Edge154 TCP/H2 及已检查 H3 字段一致,包括 Chromium encoder stream10
✓ Chrome Android154
新真实 Android154:已检查 TLS/TP/SETTINGS/Initial 与 QPACK stream10 一致,确认 PSK 及 qz 早期请求
✓ HTTP/3
六个配置的 342 个 QUIC 连接在所列稳定字段上无差异,300 个首次用于 GREASE/QPACK,42 个用于首次/恢复,并非所有字节普遍相同
✓ HTTP/2
目标配置
✓ trust_anchors
Chrome:ID 集合
✓ Client Hints
桌面 Client Hints 已对齐,iOS WebKit 无桌面 CH。当前 /client 要求 CriOS/EdgiOS 提供 CH 属于检测器分类错误
✓ GREASE/随机排序
序列确认结构、变化与随机排序,不声称普遍统计等价
✓ 会话恢复
Safari TCP 无 PSK,六个配置均确认 H3 PSK 与早期 HTTP。Edge:QUIC0-RTT4/4、早期 HTTP2/4,Firefox156 无完整恢复 TCP 基准
✓ 集成
通过 HTTP/SOCKS 代理连接,无需在程序源码中嵌入库。相应 HTTPS 模式需配置信任 CA。
✓ 所需配置
现成 154/156/26
✓ 配置更新
产品数据库,发布后五天内
✓ 代码/技术栈
通过代理支持不同技术栈、旧版和第三方软件,无需源码。兼容性取决于所需代理模式及 CA 信任。
2. httpcloak1.7.2

优势: 此次测试中库方案的 Chrome QUIC 确认表现最佳

弱点/局限: 未精确覆盖全部当前目标,自定义配置需维护。H3:auto 保持 TCP,q/qd 空闲后及拒绝 0-RTT 时出错,retry=2 无效。

结论: Chrome H3 优于 Go/noble,现成覆盖不及 BlankTrail

✓ Chrome154
custom154/H2
△ Safari26 mac/iOS
iOS:TLS 摘要一致,H2 不同,无 Mac 预设
✕ Firefox156
Latest 不是 156,H3 不同
✕ Edge154
Chrome 配 Edge UA:多余 51764
△ Chrome Android154
CH154 后的 H2 latest
△ HTTP/3
Chrome:已检查字段一致,FF/Safari 不同
△ HTTP/2
Chrome 是,Safari 否
✓ trust_anchors
Chrome:ID 集合
△ Client Hints
custom 已对齐,其他目标需手动
△ GREASE/随机排序
Chrome:已观察,并非全部目标
✓ 会话恢复
Chrome PSK 被接受,Safari 重复无 PSK
△ 集成
JSON 配置与 API
△ 所需配置
154 手动,latest152
△ 配置更新
项目更新预设,自定义配置自行维护
△ 代码/技术栈
多个 SDK,需集成
3. Go tls-client1.16.0

优势: TLS/H2 构造能力,已测 Chrome H2 准确

弱点/局限: Mac Safari16、当前 Edge/Firefox、QUIC/SETTINGS、QPACK 对 ?0 的 Huffman。H3:第二次请求即恢复,无早期 GET,已处理拒绝 0-RTT。

结论: H2 构造能力强,H3 拉低综合结果

✓ Chrome154
152_PSK:154 H2 字段
△ Safari26 mac/iOS
iOS26 首次 H2,mac16 过旧
✕ Firefox156
148 不是 156
✕ Edge154
Chrome 配置不是 Edge154
△ Chrome Android154
152_PSK/H2 配 Android CH154
✕ HTTP/3
QUIC TLS/CID,152_PSK SETTINGS 仅 51,QPACK 对 ?0 编码不同
△ HTTP/2
Chrome/iOS 是,mac16 否
✓ trust_anchors
Chrome H2:ID 集合
△ Client Hints
由调用代码设置
△ GREASE/随机排序
Chrome TCP 是,QUIC 不同
△ 会话恢复
Chrome 是,iOS26 无 PSK,mac16 过旧
△ 集成
Go API,需编写代码
△ 所需配置
无 154,配置/请求头需手动
△ 配置更新
核心发布加自定义维护
△ 代码/技术栈
Go,其他语言通过封装
4. noble-tls0.1.9 / native1.16.0

优势: 方便的异步接口及 Go tls-client 核心

弱点/局限: H3 有差异,封装/核心版本分离。H3:protocol racing 中首个 GET 在 H2/H3 重复,无早期 GET,已处理拒绝 0-RTT。

结论: 维护成本高于直接 Go API

✓ Chrome154
152_PSK:154 H2 字段
△ Safari26 mac/iOS
iOS26/H2,mac16 不同
✕ Firefox156
148 不是 156
✕ Edge154
Chrome 配置不是 Edge154
△ Chrome Android154
152_PSK/H2 配 CH154
✕ HTTP/3
QUIC 不同,封装的原始 QPACK 未单独采集
△ HTTP/2
Chrome/iOS 是
✓ trust_anchors
Chrome H2:ID 集合
△ Client Hints
由 Python 代码设置
△ GREASE/随机排序
TCP 是,QUIC 不同
△ 会话恢复
Chrome 是,iOS26 无 PSK,mac16 过旧
✓ 集成
Python async API
△ 所需配置
新名称经原生核心使用,枚举滞后
△ 配置更新
软件包与原生核心分别更新
△ 代码/技术栈
Python 加原生二进制
5. wreq Python0.12.3

优势: Safari H2 预设较好,支持平台选择

弱点/局限: trust anchor 为空,CH 过旧,H3 未工作

结论: 已检查 Chrome TLS 字段表现优于 primp

△ Chrome154
153:JA4/H2 一致,原始字段有缺陷
△ Safari26 mac/iOS
26 mac/iOS H2 摘要
✕ Firefox156
151 不是 156
✕ Edge154
148 不是 154
△ Chrome Android154
153:H2 摘要
✕ HTTP/3
HTTP_3: NO_APPLICATION_PROTOCOL
✓ HTTP/2
Chrome/Safari 摘要
✕ trust_anchors
51764 为空
✕ Client Hints
UA154 配 153
△ GREASE/随机排序
sigGREASE/随机排序,全部目标的原始检查覆盖不完整
✓ 会话恢复
Chrome PSK,Safari26 重复无 PSK
✓ 集成
Python sync/async
✕ 所需配置
无现成 154
△ 配置更新
wreq 发布,需更新依赖
△ 代码/技术栈
Python/Rust,独立 Node 包
6. primp2.0.1 (Python)

优势: API 简单,预设丰富

弱点/局限: trust anchors/ALPS/GREASE、Safari PSK 不同、H2 关闭错误

结论: 易用性无法弥补原始差异

△ Chrome154
153:摘要一致,原始字段不同
△ Safari26 mac/iOS
26:摘要一致,原始字段不同
✕ Firefox156
151 不是 156
✕ Edge154
151:原始签名/ALPS 不同
△ Chrome Android154
153:H2 摘要
✕ HTTP/3
测试的 Python primp2.0.1 包构建时未启用 http3 feature,不提供 QUIC/H3 API。Rust 核心有可选独立 http3 feature,但属于另一种构建,其结果不能用于 Python 包。
✓ HTTP/2
已获得摘要
✕ trust_anchors
51764 为空
✕ Client Hints
UA154 配 153
✕ GREASE/随机排序
Chrome sigalgs 无 GREASE
✕ 会话恢复
Safari26:接受 PSK 1 次,丢失 2/4 响应
✓ 集成
Python sync/async
✕ 所需配置
无 154
△ 配置更新
软件包发布,自定义有限
△ 代码/技术栈
Python/Rust 传输
7. wreq-js3.2.0

优势: Safari H2 及熟悉的 fetch

弱点/局限: Chrome/Edge 过旧,未获得精确 154

结论: 不及较新的 Python 预设

✕ Chrome154
149:TLS 不同
△ Safari26 mac/iOS
26 mac/iOS H2 摘要
✕ Firefox156
151 不是 156
✕ Edge154
148 不是 154
✕ Chrome Android154
149:TLS 不同
✕ HTTP/3
wreq-js3.2.0 及其使用的 wreq0.16.1 没有原生 QUIC/H3 传输。TLS 配置类型中的 HTTP3 ALPN 不会创建 QUIC 传输,auto 请求使用 TCP/H2。
✓ HTTP/2
Chrome/Safari 摘要
✕ trust_anchors
缺少所需载荷
✕ Client Hints
旧预设,需手动
△ GREASE/随机排序
有 overrides,但未获得当前 154
△ 会话恢复
Safari26 无 PSK,未获得精确 Chrome154
✓ 集成
Fetch API Node/Bun
✕ 所需配置
拒绝 154
△ 配置更新
npm/核心发布
△ 代码/技术栈
Node/Bun,需集成代码
8. curl_cffi0.16.3 / curl-impersonate

优势: API 丰富,H3 可用,集成成本低

弱点/局限: TLS/QUIC 与当前目标不一致。H3 空闲后 PSK 有效,但测试配置未提出早期数据。

结论: H3 与灵活性有用,但未获得精确 154

✕ Chrome154
150:无 51764/sigGREASE
✕ Safari26 mac/iOS
Safari260:原始/QUIC 差异
✕ Firefox156
147:不是 156,旧恢复握手缺陷
✕ Edge154
Edge101 过旧
✕ Chrome Android154
Android131 过旧
✕ HTTP/3
Chrome SETTINGS 一致,TLS/Initial154 及 Safari 原始字段不同
✓ HTTP/2
Chrome H2 一致
✕ trust_anchors
无 51764
△ Client Hints
手动请求头/预设
✕ GREASE/随机排序
无目标 154 的 sigGREASE
✕ 会话恢复
Safari:接受 PSK 3 次,Firefox 恢复时保留 35
✓ 集成
Requests API sync/async
✕ 所需配置
无 154,自定义尝试未匹配
△ 配置更新
库发布,自定义自行维护
△ 代码/技术栈
Python/libcurl/CLI 生态
9. rnet2.4.2

优势: 现成预设及同步/异步

弱点/局限: 目录过旧,H3 API 拒绝请求

结论: 配置可用性限制结果

✕ Chrome154
137 过旧
△ Safari26 mac/iOS
18.5:26 摘要,原始字段不同
✕ Firefox156
139 不是 156
✕ Edge154
134 不是 154
✕ Chrome Android154
137 配 Android UA 不同
✕ HTTP/3
HTTP_3: UnsupportedVersion
✓ HTTP/2
Chrome/Safari 摘要
✕ trust_anchors
无 51764
✕ Client Hints
旧预设 CH
✕ GREASE/随机排序
sigalgs/ALPS 过旧
△ 会话恢复
Safari 重复无 PSK,完整当前配置未确认
✓ 集成
Python sync/async
✕ 所需配置
无 154
△ 配置更新
软件包更新
△ 代码/技术栈
Python/Rust
10. Python tls-client1.0.1

优势: 上手门槛低

弱点/局限: 核心与目录严重滞后

结论: API 方便,传输实现过旧

✕ Chrome154
120 过旧
✕ Safari26 mac/iOS
Safari15.6 过旧
✕ Firefox156
使用 firefox_120 与 Firefox156 UA 发四次请求。原始组为 29,23,24,25,256,257,基准 156 含 4588,集合不同。目录 1.0.1 无现成 156。
✕ Edge154
目录 1.0.1 无现成 Edge154。测试 Chromium chrome_120 配 Edge154 UA:组无 4588,旧 ALPS17513,signature_algorithms 无基准 GREASE。
✕ Chrome Android154
120 配 Android UA 不同
✕ HTTP/3
已安装 Python 封装 1.0.1 及附带原生传输无原生 HTTP/3 API,未获得 QUIC 连接。
✓ HTTP/2
Chrome H2 摘要
✕ trust_anchors
无 51764
△ Client Hints
手动设置请求头
✕ GREASE/随机排序
组/ALPS 过旧
△ 会话恢复
Safari15.6 无 PSK,但首次 TLS 过旧
✓ 集成
Python,类似 requests
✕ 所需配置
154 名称不能产生正确配置
△ 配置更新
原生核心与软件包需更新
△ 代码/技术栈
Python/native
已测试原生配置详情

Python tls-client1.0.1: firefox_120 配 UA156 保留无 4588 的旧组,Chromium 配置搭配 Edge154 UA 保留旧 ALPS 与签名算法。无现成目标版本。 req/v3: ImpersonateSafari 和 ImpersonateFirefox 使用旧 Safari16/Firefox120 配置,Chrome 预设为 120。 uTLS1.8.2: Auto 选择 Chrome133、Firefox120、Safari16 和 Edge85,其新 TCP 连接不符合当前目标。自定义 ClientHelloSpec 可构建另一种配置,但不会使这些现成配置变新。版本与预设可查看 API req/v3 和 API uTLS1.8.2.

已测试原生配置详情

HTTP/3 按具体发行包评估。 测试的 Python primp2.0.1 无 QUIC,其 Python 构建 不含 Rust 核心可选 http3 feature。以下方案中: wreq-js3.2.0、Python tls-client1.0.1、got-scraping4.2.1 和普通对照传输均无 HTTP/3。uTLS + Go HTTP/2 也无 QUIC,添加独立 QUIC 客户端意味着测试另一方案。

11. req/v3 3.61.0

优势: 灵活 TLS/H2 API 及可用 H3

弱点/局限: 内置 Chrome 不是当前目标。H3 连接跨空闲期保持,服务器关闭后的新握手无 PSK/0-RTT。

结论: 现成 HTTP3 API 优于底层 uTLS

✕ Chrome154
ImpersonateChrome 不同
✕ Safari26 mac/iOS
测试四个新 TCP 连接:Safari16 配目标版本 UA。无现成当前配置,稳定 TLS 字段与基准不同。uTLS 的 HTTP/2 仍为独立传输。结果仅针对这些预设,不否认构建自定义 ClientHelloSpec 的能力。
✕ Firefox156
测试四个新 TCP 连接:Firefox120 配目标版本 UA。无现成当前配置,稳定 TLS 字段与基准不同。uTLS 的 HTTP/2 仍为独立传输。结果仅针对这些预设,不否认构建自定义 ClientHelloSpec 的能力。
✕ Edge154
测试四个新 TCP 连接:Chrome120 配目标版本 UA。无现成当前配置,稳定 TLS 字段与基准不同。uTLS 的 HTTP/2 仍为独立传输。结果仅针对这些预设,不否认构建自定义 ClientHelloSpec 的能力。
✕ Chrome Android154
测试四个新 TCP 连接:Chrome120 配目标版本 UA。无现成当前配置,稳定 TLS 字段与基准不同。uTLS 的 HTTP/2 仍为独立传输。结果仅针对这些预设,不否认构建自定义 ClientHelloSpec 的能力。
✕ HTTP/3
H3 可用,原始字段/SETTINGS 不同
△ HTTP/2
可配置,但未匹配目标
✕ trust_anchors
无所需 51764
△ Client Hints
手动请求头
✕ GREASE/随机排序
未复现测试的 154
✕ 会话恢复
ImpersonateChrome/Safari/Firefox 各四个新 TCP 会话,无 pre_shared_key。未复现 Chromium/Firefox 恢复指纹变化,旧 Safari 配置不能确认当前 Safari 整体一致。
△ 集成
Go API/底层选项
△ 所需配置
需组装所需配置
△ 配置更新
数据库部分覆盖,自定义自行维护
△ 代码/技术栈
Go
12. uTLS + Go HTTP2

优势: ClientHelloSpec 自由度高

弱点/局限: 仅 TLS 不能修复 HTTP2/3

结论: 构建客户端的工具,并非现成目标

✕ Chrome154
现成预设不是 154
✕ Safari26 mac/iOS
测试四个新 TCP 连接:Safari16 配目标版本 UA。无现成当前配置,稳定 TLS 字段与基准不同。uTLS 的 HTTP/2 仍为独立传输。结果仅针对这些预设,不否认构建自定义 ClientHelloSpec 的能力。
✕ Firefox156
测试四个新 TCP 连接:Firefox120 配目标版本 UA。无现成当前配置,稳定 TLS 字段与基准不同。uTLS 的 HTTP/2 仍为独立传输。结果仅针对这些预设,不否认构建自定义 ClientHelloSpec 的能力。
✕ Edge154
测试四个新 TCP 连接:Edge85 配目标版本 UA。无现成当前配置,稳定 TLS 字段与基准不同。uTLS 的 HTTP/2 仍为独立传输。结果仅针对这些预设,不否认构建自定义 ClientHelloSpec 的能力。
✕ Chrome Android154
测试四个新 TCP 连接:Chrome133 配目标版本 UA。无现成当前配置,稳定 TLS 字段与基准不同。uTLS 的 HTTP/2 仍为独立传输。结果仅针对这些预设,不否认构建自定义 ClientHelloSpec 的能力。
✕ HTTP/3
测试的 uTLS + golang.org/x/net/http2 组合无 QUIC/HTTP3 传输,加入其他 QUIC 库即成为另一组合。
✕ HTTP/2
标准 Go H2 不同
✓ trust_anchors
ClientHelloSpec 原生 GenericExtension 发送了基准 trust_anchors51764 载荷。四次请求成功,抓到的扩展字节一致。仍需手动组装 Spec,并非现成当前浏览器配置。无 PSK 的 Spec 使用 PreferSkipResumptionOnNilExtension=true。
△ Client Hints
手动
△ GREASE/随机排序
Spec 灵活,需配置
△ 会话恢复
Cache/Spec 由开发者管理
✕ 集成
底层集成
△ 所需配置
分别构建 TLS 与 H2
✕ 配置更新
自定义配置自行维护
△ 代码/技术栈
Go,自定义传输
已测试原生配置详情

底层能力单独评估:uTLS 的 ClientHelloSpec 原生 GenericExtension 发送了基准 trust_anchors51764。四次成功请求及原始 ClientHello 确认该扩展字节一致,因此相应列为绿色。仍需手动组装 Spec 与独立 H2 传输,一个扩展一致并不会让现成 Chrome133 变为当前 Chrome154。

13. impit0.14.5

优势: 简单 API 与可用 H3

弱点/局限: 无精确当前 Chrome/Safari,有 H2/QUIC 缺陷。H3 空闲后 PSK 有效,但无早期 HTTP。

结论: 支持 H3 并未提高模拟准确度

✕ Chrome154
151:TLS/H2 不同
✕ Safari26 mac/iOS
测试枚举无 Safari
✕ Firefox156
144 不是 156
✕ Edge154
Chrome 配 Edge UA 不是 Edge
✕ Chrome Android154
Android:TLS/H2 不同
✕ HTTP/3
H3 可用,原始字段差异很大
✕ HTTP/2
SETTINGS/窗口不同
✕ trust_anchors
无所需 51764
△ Client Hints
需协调请求头
✕ GREASE/随机排序
QUIC 保留类似 TCP 的集合
✕ 会话恢复
重复 TLS 不同
✓ 集成
Fetch Python/Node
✕ 所需配置
拒绝 154
△ 配置更新
项目发布
△ 代码/技术栈
Python/Node/native
14. CycleTLS2.0.5

优势: 原生 JA3/JA4R/H2 参数、可用 H3、手动匹配 Firefox H2 摘要

弱点/局限: Chrome154 JA3 拒绝扩展 51764,JA4R 改变组,JA3/联合设置选择 TLS1.2。简要检测识别 Safari,但原始字段不同。强制 H3 每次 GET 使用独立首次连接,无 PSK/0-RTT。

结论: 构造能力灵活,但测试设置未完整复现当前目标,有限 Safari/H2 成功以黄色表示

✕ Chrome154
JA3/H2 custom154:握手错误
△ Safari26 mac/iOS
原生手动 JA4R 获得四次成功 TLS1.3 请求,简要检测识别 Safari26。原始 supported_groups 为 29,29,23,24,而非含 4588 的集合,未精确匹配 Safari。JA3 及 JA3+JA4R 联合设置选择 TLS1.2。
✕ Firefox156
使用基准 Firefox156 HTTP2Fingerprint 测试 JA3、JA4R 及联合传入。JA3/联合模式得到 TLS1.2 而非 TLS1.3,JA4R 改组后握手失败。未获得完整 156 指纹。
✕ Edge154
测试 JA3/JA4R 及联合 Edge154 配置。JA3/联合设置得到 TLS1.2 和不同 signature_algorithms,JA4R 握手错误。H2 也有多余/不同 SETTINGS。
✕ Chrome Android154
手动 Chrome154 配置用于 Android 目标时拒绝扩展 51764(trust_anchors)。独立 JA4R 也未成功握手,测试设置未达目标。
✕ HTTP/3
H3 可用,JA3 未产生所需 QUIC
△ HTTP/2
手动传入 Firefox HTTP2Fingerprint 得到一致 H2 摘要:1:65536,4:131072,5:16384|12517377|0|m,p,a,s。Chrome/Edge/Safari 配置未完整复现 SETTINGS,未全面通过所有目标 H2。
✕ trust_anchors
H2 中扩展 51764 错误
△ Client Hints
手动配置请求头
✕ GREASE/随机排序
QUIC 集合/组不同
△ 会话恢复
成功 Safari JA4R 测试的四次首次 TLS1.3 Hello 无 PSK,符合 Safari 无 TCP 恢复,但原始字段不同。未获得当前 Chromium/Firefox PSK 变化。
△ 集成
Node 加原生/显式参数
△ 所需配置
JA3/JA4/H2 配置,并非现成 154
✕ 配置更新
自定义自行维护
△ 代码/技术栈
Node/原生,需集成
已测试原生配置详情

CycleTLS2.0.5: 测试三种原生设置:JA3 配基准 H2 摘要、JA4R 配签名算法、JA3+JA4R 联合设置。Chrome154 JA3 拒绝扩展 51764。单独 JA4R 设置不同组,Chrome/Edge/Firefox 握手失败。Safari JA4R 获得四次成功 TLS1.3 请求及简要 Safari26 识别,但原始组 29,29,23,24 不同于含 4588 的基准。JA3 和联合设置选择 TLS1.2。手动 Firefox H2 摘要一致,因此计为部分符合。设置见 CycleTLS 原生 API,这清楚展示了简要摘要与完整指纹的区别。

15. got-scraping4.2.1

优势: 方便的请求头生成器

弱点/局限: 停止维护,非浏览器传输

结论: 请求头不能弥补 TLS/H2

✕ Chrome154
请求头 154,TLS/H2 不同
✕ Safari26 mac/iOS
使用 Safari26.6.2 请求头发四次请求。生成器改变请求头与部分 TLS 选项,但原始 TLS 字段和 H2 不符合浏览器。所有 H2 摘要为 2:0,4:33554432|4128769|0|m,p,a,s。
✕ Firefox156
使用 Firefox156 请求头发四次请求。生成器改变请求头与部分 TLS 选项,但原始 TLS 字段和 H2 不符合浏览器。所有 H2 摘要为 2:0,4:33554432|4128769|0|m,p,a,s。
✕ Edge154
使用 Edge154 请求头发四次请求。生成器改变请求头与部分 TLS 选项,但原始 TLS 字段和 H2 不符合浏览器。所有 H2 摘要为 2:0,4:33554432|4128769|0|m,p,a,s。
✕ Chrome Android154
使用 Chrome Android154 请求头发四次请求。生成器改变请求头与部分 TLS 选项,但原始 TLS 字段和 H2 不符合浏览器。所有 H2 摘要为 2:0,4:33554432|4128769|0|m,p,a,s。
✕ HTTP/3
got-scraping4.2.1 使用 Node TLS 与 http2-wrapper,无 QUIC/HTTP3 API。auto 测试使用 TCP/H2。
✕ HTTP/2
非 Chrome
✕ trust_anchors
无所需 51764
✓ Client Hints
请求头 154 生成器
✕ GREASE/随机排序
传输非 Chrome
✕ 会话恢复
重复 TCP 测量无 pre_shared_key。切换浏览器请求头未复现 Chromium 或 Firefox 首次/恢复指纹。结果仅针对测试的 got-scraping 配置。
✓ 集成
Got/Node API
✕ 所需配置
无 154 传输
✕ 配置更新
停止维护,无当前维护
△ 代码/技术栈
Node
16. HTTPX0.28.1

优势: 可靠、熟悉的 HTTP API

弱点/局限: 改 UA 不能替代 TLS/H2/QUIC

结论: 对照客户端,非模拟方案

✕ Chrome154
对照:非 Chrome
✕ Safari26 mac/iOS
无浏览器配置。使用此目标 UA 的请求保留自身 TLS 指纹,修改 UA 不能复现浏览器。
✕ Firefox156
无浏览器配置。使用此目标 UA 的请求保留自身 TLS 指纹,修改 UA 不能复现浏览器。
✕ Edge154
无浏览器配置。使用此目标 UA 的请求保留自身 TLS 指纹,修改 UA 不能复现浏览器。
✕ Chrome Android154
无浏览器配置。使用此目标 UA 的请求保留自身 TLS 指纹,修改 UA 不能复现浏览器。
✕ HTTP/3
测试的原生传输无 HTTP/3,未获得浏览器 QUIC 指纹。
△ HTTP/2
HTTP2 已启用,但不同
✕ trust_anchors
抓到的 ClientHello 缺少带基准 Chrome154 ID 集合的 trust_anchors。
△ Client Hints
可手动设置
✕ GREASE/随机排序
抓到的 ClientHello 缺少浏览器 GREASE 及相应 Chromium 扩展随机排序。
✕ 会话恢复
测试配置重新连接后无 Chrome/Firefox PSK 变化。curl 在同一进程发四次请求,Python 保留客户端。这仅描述该配置,并非声称 TLS 后端完全不支持会话。
✓ 集成
Python sync/async
✕ 所需配置
无内置浏览器 TLS/H2/QUIC 配置数据库,User-Agent 头不是配置。
✕ 配置更新
无浏览器指纹数据库,更新 HTTP 客户端也不会获得此数据库。
△ 代码/技术栈
Python
17. Go net/http

优势: 可靠、熟悉的 HTTP API

弱点/局限: 改 UA 不能替代 TLS/H2/QUIC

结论: 对照客户端,非模拟方案

✕ Chrome154
对照:非 Chrome
✕ Safari26 mac/iOS
无浏览器配置。使用此目标 UA 的请求保留自身 TLS 指纹,修改 UA 不能复现浏览器。
✕ Firefox156
无浏览器配置。使用此目标 UA 的请求保留自身 TLS 指纹,修改 UA 不能复现浏览器。
✕ Edge154
无浏览器配置。使用此目标 UA 的请求保留自身 TLS 指纹,修改 UA 不能复现浏览器。
✕ Chrome Android154
无浏览器配置。使用此目标 UA 的请求保留自身 TLS 指纹,修改 UA 不能复现浏览器。
✕ HTTP/3
测试的原生传输无 HTTP/3,未获得浏览器 QUIC 指纹。
△ HTTP/2
支持 HTTP2,但不同
✕ trust_anchors
抓到的 ClientHello 缺少带基准 Chrome154 ID 集合的 trust_anchors。
△ Client Hints
可手动设置
✕ GREASE/随机排序
抓到的 ClientHello 缺少浏览器 GREASE 及相应 Chromium 扩展随机排序。
△ 会话恢复
确认服务端接受 TLS1.3 PSK 恢复。重复请求保留自身 Go/Node 指纹,未模拟目标浏览器变化。
✓ 集成
标准 Go API
✕ 所需配置
无内置浏览器 TLS/H2/QUIC 配置数据库,User-Agent 头不是配置。
✕ 配置更新
无浏览器指纹数据库,更新 HTTP 客户端也不会获得此数据库。
△ 代码/技术栈
Go
已测试原生配置详情

重复 TLS: 启用 ClientSessionCache 的 Go net/http 和 Node 内置 fetch 获得服务端接受的 PSK,但保留非浏览器 ClientHello。这是部分传输能力,并非已确认的恢复浏览器模拟。HTTPX、requests、Windows curl 及现成 req/v3 配置在测试设置中未产生所需 Chromium/Firefox PSK 变化。评估描述这些配置可复现的结果,并非 TLS 后端本身无法保存会话。Safari 无 TCP PSK 以 Safari 基准比较,本身不扣分。

18. Windows curl / Schannel

优势: 可靠、熟悉的 HTTP API

弱点/局限: 改 UA 不能替代 TLS/H2/QUIC

结论: 对照客户端,非模拟方案

✕ Chrome154
对照:非 Chrome
✕ Safari26 mac/iOS
无浏览器配置。使用此目标 UA 的请求保留自身 TLS 指纹,修改 UA 不能复现浏览器。
✕ Firefox156
无浏览器配置。使用此目标 UA 的请求保留自身 TLS 指纹,修改 UA 不能复现浏览器。
✕ Edge154
无浏览器配置。使用此目标 UA 的请求保留自身 TLS 指纹,修改 UA 不能复现浏览器。
✕ Chrome Android154
无浏览器配置。使用此目标 UA 的请求保留自身 TLS 指纹,修改 UA 不能复现浏览器。
✕ HTTP/3
测试的原生传输无 HTTP/3,未获得浏览器 QUIC 指纹。
✕ HTTP/2
H2 取决于构建,测得传输不同
✕ trust_anchors
抓到的 ClientHello 缺少带基准 Chrome154 ID 集合的 trust_anchors。
△ Client Hints
可手动设置
✕ GREASE/随机排序
抓到的 ClientHello 缺少浏览器 GREASE 及相应 Chromium 扩展随机排序。
✕ 会话恢复
测试配置重新连接后无 Chrome/Firefox PSK 变化。curl 在同一进程发四次请求,Python 保留客户端。这仅描述该配置,并非声称 TLS 后端完全不支持会话。
✓ 集成
CLI/代理
✕ 所需配置
无内置浏览器 TLS/H2/QUIC 配置数据库,User-Agent 头不是配置。
✕ 配置更新
无浏览器指纹数据库,更新 HTTP 客户端也不会获得此数据库。
△ 代码/技术栈
跨技术栈 CLI
19. requests2.32.5

优势: 可靠、熟悉的 HTTP API

弱点/局限: 改 UA 不能替代 TLS/H2/QUIC

结论: 对照客户端,非模拟方案

✕ Chrome154
对照:非 Chrome
✕ Safari26 mac/iOS
无浏览器配置。使用此目标 UA 的请求保留自身 TLS 指纹,修改 UA 不能复现浏览器。
✕ Firefox156
无浏览器配置。使用此目标 UA 的请求保留自身 TLS 指纹,修改 UA 不能复现浏览器。
✕ Edge154
无浏览器配置。使用此目标 UA 的请求保留自身 TLS 指纹,修改 UA 不能复现浏览器。
✕ Chrome Android154
无浏览器配置。使用此目标 UA 的请求保留自身 TLS 指纹,修改 UA 不能复现浏览器。
✕ HTTP/3
测试的原生传输无 HTTP/3,未获得浏览器 QUIC 指纹。
✕ HTTP/2
H1,此传输无 H2
✕ trust_anchors
抓到的 ClientHello 缺少带基准 Chrome154 ID 集合的 trust_anchors。
△ Client Hints
可手动设置
✕ GREASE/随机排序
抓到的 ClientHello 缺少浏览器 GREASE 及相应 Chromium 扩展随机排序。
✕ 会话恢复
测试配置重新连接后无 Chrome/Firefox PSK 变化。curl 在同一进程发四次请求,Python 保留客户端。这仅描述该配置,并非声称 TLS 后端完全不支持会话。
✓ 集成
Python sync
✕ 所需配置
无内置浏览器 TLS/H2/QUIC 配置数据库,User-Agent 头不是配置。
✕ 配置更新
无浏览器指纹数据库,更新 HTTP 客户端也不会获得此数据库。
△ 代码/技术栈
Python
20. Node fetch

优势: 可靠、熟悉的 HTTP API

弱点/局限: 改 UA 不能替代 TLS/H2/QUIC

结论: 对照客户端,非模拟方案

✕ Chrome154
对照:非 Chrome
✕ Safari26 mac/iOS
无浏览器配置。使用此目标 UA 的请求保留自身 TLS 指纹,修改 UA 不能复现浏览器。
✕ Firefox156
无浏览器配置。使用此目标 UA 的请求保留自身 TLS 指纹,修改 UA 不能复现浏览器。
✕ Edge154
无浏览器配置。使用此目标 UA 的请求保留自身 TLS 指纹,修改 UA 不能复现浏览器。
✕ Chrome Android154
无浏览器配置。使用此目标 UA 的请求保留自身 TLS 指纹,修改 UA 不能复现浏览器。
✕ HTTP/3
测试的原生传输无 HTTP/3,未获得浏览器 QUIC 指纹。
✕ HTTP/2
实测 H1
✕ trust_anchors
抓到的 ClientHello 缺少带基准 Chrome154 ID 集合的 trust_anchors。
△ Client Hints
可手动设置
✕ GREASE/随机排序
抓到的 ClientHello 缺少浏览器 GREASE 及相应 Chromium 扩展随机排序。
△ 会话恢复
确认服务端接受 TLS1.3 PSK 恢复。重复请求保留自身 Go/Node 指纹,未模拟目标浏览器变化。
✓ 集成
内置 fetch
✕ 所需配置
无内置浏览器 TLS/H2/QUIC 配置数据库,User-Agent 头不是配置。
✕ 配置更新
无浏览器指纹数据库,更新 HTTP 客户端也不会获得此数据库。
△ 代码/技术栈
Node

浏览器指纹由 TLS、HTTP2/3、请求头和下一次连接行为共同构成。应根据已测试目标与维护成本选择方案,预设中的浏览器名称及修改 User-Agent 不能代替这些测量。

BlankTrail Proxy 的免费 Lite 套餐开放全部浏览器配置库,可以下载应用,自行测试所需配置。

推荐阅读