详解
当您的客户端建立 TLS 连接时,最开始的几个字节是一个 ClientHello 数据包,其中描述了您的客户端支持哪些加密套件、TLS 版本、扩展、椭圆曲线以及 ALPN 值。这些属性的具体列表和排列顺序因实现而异——Chrome 的 ClientHello 与 Firefox 的不同,Firefox 的与 curl 的不同,curl 的又与 Python 的 `requests` 库不同,以此类推。
JA3(及其后继版本 JA4)是一种哈希格式,能够将 ClientHello 的结构转换为一个简短的标识符。反爬虫厂商会对每一个传入的 TLS 连接计算该哈希值,并与已知特征库进行比对。如果您的爬虫使用 Python `requests`,您的 TLS 指纹将与 OpenSSL 默认值相匹配,并会被立即识别为"非真实浏览器"——甚至在您发送任何一个 HTTP 字节之前就已如此。
这正是为什么许多爬虫在 Cloudflare、Akamai 及类似技术栈上失败的原因,即便 IP 和 User-Agent 看起来完全正常。TLS 层会暴露出该请求并非来自 Chrome。现代隐身库(如 `curl_cffi`、`tls-client`,以及配合正确启动参数的 Playwright)会模拟真实浏览器的 TLS 指纹,从而规避这一检测。
工作原理
JA3 从 ClientHello 的五个字段构建指纹:TLS 版本、支持的加密套件、支持的扩展、支持的椭圆曲线以及支持的椭圆曲线点格式。它将这些字段拼接后进行 MD5 哈希,生成一个 32 字符的签名。
JA4(现代替代方案)在此基础上扩展了 ALPN、版本、SNI 是否存在、GREASE 处理,并以一种对随机化具有鲁棒性的稳定方式对扩展进行排序。JA4 还具有针对 QUIC(JA4Q)、HTTP(JA4H)和 SSL 会话(JA4S)的变体。服务器计算指纹后,将其与允许/拒绝列表进行比对,或将其与其他信号一起输入风险评分模型。