Skip to main content

chrome-fp — 与真 Chrome 逐字节同指纹的纯 Python 请求库

用 Python 发 HTTP 请求,但 TLS/HTTP2 指纹跟本机真 Chrome(152.0.7977.64)完全一致: JA4、HTTP/2 Akamai 指纹、请求头顺序、扩展集合、GREASE、ALPS、trust_anchors、PQ 混合密钥共享(X25519MLKEM768)全都一致。

不依赖 curl/Go/浏览器,握手是自己实现的(ssl 模块无法自定义 ClientHello,所以只借用 cryptography 的密码原语)。

实测结果(第三方服务器 tls.peet.ws 判定)

项目 真 Chrome 152 本库
JA4 t13d1517h2_8daaf6152771_cb7bf5808d99 完全一致
HTTP/2 Akamai 1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p 完全一致
请求头顺序 :method :authority :scheme :path sec-ch-ua … priority 完全一致
扩展数 19(17 真实 + 2 GREASE) 一致

离线自检(tools/verify_hello.py)用 26 条真机抓包做基准,43/43 通过: 密码套件列表与顺序、17 个扩展内容逐字节、GREASE 首空尾 1 字节、扩展随机置换、trust_anchors 32 个 ID 集合、 key_share 三项(GREASE 1B / X25519MLKEM768 1216B / x25519 32B)、ECH GREASE 长度集合 {186,218,250,282}、SNI、ALPS、压缩证书、签名算法。

快速开始

cd ~/PycharmProjects/chrome-fp
python3 -m venv .venv && ./.venv/bin/pip install cryptography hpack brotli zstandard certifi
from chrome_fp import Session

s = Session(proxy="http://127.0.0.1:7892")          # 可选代理
r = s.get("https://tls.peet.ws/api/all")
d = r.json()
print(d["tls"]["ja4"])                             # 与真 Chrome 一致
print(d["http2"]["akamai_fingerprint"])

r = s.post("https://httpbin.org/post", json={"a": 1})
print(r.status_code, r.json())
s.close()

Session 提供 requests 风格 API:get/post/put/delete/head/patch/options、 params/data/json/headers/timeout/allow_redirects、cookie jar、gzip/deflate/br/zstd 自动解压、 HTTP/2 与 HTTP/1.1 自适应(按 ALPN)、代理 CONNECT、证书链校验(浏览器语义:EKU 缺失放行、主机名通配符)。

关键参数

Session(
    proxy="http://127.0.0.1:7892",  # 代理
    verify=True,                    # 证书链 + 主机名校验
    timeout=30,                     # 秒
    mode="navigate",                # navigate | cors | no-cors(决定 sec-fetch-*/accept)
    headers={"referer": "..."},     # 追加请求头
    user_agent=None,                # 覆盖 UA
    send_priority_tree=True,        # 发 Chrome 的 PRIORITY 树(3/5/7/9),Akamai 指纹需要
)

底层构造单条 ClientHello(不含网络):

from chrome_fp import build_client_hello, ja4_from_hello
ch = build_client_hello("example.com")
print(ja4_from_hello(ch.record))
ch.record          # 可直接写 socket 的原始字节
  • include_mlkem=False:不发 X25519MLKEM768(老服务器/只想用 x25519 时)
  • grease_parts=():完全关闭 GREASE;("cipher","ext") 之类可细粒度控制
  • permute_extensions=False:关闭扩展随机置换(调试用)

目录结构

chrome_fp/
  spec.py         Chrome 152 指纹常量(全部标注源码出处)
  hello.py        按 BoringSSL ssl_add_clienthello_tlsext 规则拼 ClientHello
  fingerprint.py  解析 + JA3/JA4 计算
  tls13.py        纯 Python TLS 1.3 客户端(record 层/密钥调度/CV 校验/证书链校验/KeyUpdate)
  tls12.py        TLS 1.2 回落(ECDHE/RSA + GCM/ChaCha20, EMS, ServerKeyExchange 验签)
  client.py       发同一个 ClientHello, 按 ServerHello 自动分派 1.3 / 1.2
  mlkem.py        ML-KEM-768 (FIPS 203) 纯 Python,供 X25519MLKEM768 混合密钥共享
  http2.py        HTTP/2 客户端(Chrome 帧序/SETTINGS/优先级/头顺序)
  http1.py        HTTP/1.1 客户端(ALPN=http/1.1 时)
  session.py      requests 风格 API
tools/            抓包/自检/诊断脚本
tests/            单元与端到端测试
data/             真 Chrome 152 的 26 条 ClientHello 抓包 + peet 指纹真值
specs/            源码提取的规格文档(含出处)

测试

./.venv/bin/python tools/verify_hello.py data/chrome152_clienthello   # 43/43
./.venv/bin/python tests/test_mlkem.py                                # 9/9  (对 pqcrypto/kyber-py 双向互操作)
./.venv/bin/python tools/verify_live.py                               # 11/11 (实网指纹: JA4/Akamai/头顺序)
./.venv/bin/python tests/test_endtoend.py                             # 28/28 (本地端到端: TLS1.3 与 TLS1.2 各 14 项)

真实站点实测(20 个):19 个成功(15 个走 TLS 1.3、4 个回落 TLS 1.2),唯一失败是 google.com(见"已知问题")。 证书链校验支持交叉签名根(Google GTS/DigiCert G2 交叉签那类),按 DER 级名称匹配 + 逐级验签 + BFS 建路 + 有效期筛选。

抓真值(需要本地 Chrome):

python3 tools/hello_sniff.py 8899 /tmp/fp_hello     # 起 CONNECT 代理并 dump ClientHello
google-chrome --headless=new --proxy-server=http://127.0.0.1:8899 https://example.com/

已知边界与说明

  • TLS 1.2 回落已实现(ECDHE + AES-GCM / ChaCha20-Poly1305,含 RSA 密钥交换,支持 EMS/ALPN/证书校验)。 用同一个 ClientHello 回落 —— 真 Chrome 就是这样,所以 JA4 等指纹不变。 实测:nginx.org / bing.com(h2 over TLS1.2)/ sohu.com / qq.com 等只支持 1.2 的站点都能正常请求。 不支持:CBC 类套件(极少见,会明确报错)、会话恢复、0-RTT、客户端证书。
  • 已知问题:www.google.com / www.googleapis.com 握手能完成(JA4 一致),但 GFE 随后会用 unexpected_message 断链 —— 它在等某个特定形态的客户端消息,本库还没对齐。其余 19/20 个实测站点正常。 (curl / Python ssl 走同一个代理访问 google 正常,所以不是代理问题。)
  • JA3 哈希每次连接都不同,这是真 Chrome 的行为(扩展顺序随机置换),不是 bug;稳定的标识是 JA4。
  • 扩展顺序、GREASE 取值、ECH GREASE 长度、trust_anchors 顺序都是每次连接随机的(与 Chrome 相同分布),所以「逐字节一致」指的是:同一连接内所有非随机字段逐字节相同 + 结构/取值集合与 Chrome 完全一致。
  • 会话恢复(PSK / session ticket)、0-RTT、客户端证书、ECH 真加密未实现。
  • QUIC/HTTP3 未实现(Chrome 走 TCP 时就是这套指纹)。

真值来源

  1. 本机真 Chrome 152.0.7977.64 的原始 ClientHello 抓包 26 条(data/chrome152_clienthello/)+ tls.peet.ws 判定结果(data/chrome152_peet.json)
  2. 本地 Chromium/BoringSSL 源码:
    • 扩展表顺序与置换:boringssl/src/ssl/extensions.cc:4067-4295, 4306-4328
    • GREASE 首尾与 padding 规则:extensions.cc:4489-4560
    • ECH GREASE 长度:boringssl/src/ssl/encrypted_client_hello.cc:732-784
    • trust_anchors(0xca34):include/openssl/tls1.h:141 + extensions.cc:2948-2965
    • 混合密钥共享拼接顺序:boringssl/src/ssl/ssl_key_share.cc:308-346(ML-KEM ss ‖ X25519 ss)
    • TLS 客户端配置:/home/wqw/chromium/src/net/socket/ssl_client_socket_impl.cc

Metadata

Release files for chrome-fp 0.2.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for chrome-fp 0.2.2
File Interpreter ABI Platform
chrome_fp-0.2.2-py3-none-any.whl Python 3 none any Details

Release files / chrome_fp-0.2.2-py3-none-any.whl

Download URL chrome_fp-0.2.2-py3-none-any.whl
Size 48.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
265423b94d2660ea5027ef4f0edfe7b3ff9a93b3fc70655ad54e9ae1772aee46
BLAKE2b-256 checksum
How to use checksums
5cfbc9c7bc8b73e2bd8c12300b4c2884ed3f4c3aa2f4c2e8a8f3b01482f4f3d6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release history Release notifications | RSS feed

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.3

1 release file

This release

0.2.2 This release

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page