首页
社区
课程
招聘
[原创] 纯 Go 复刻浏览器 TLS HTTP/2 指纹:我写了一个可开源的库(JA3/JA4 逐字节一致,零 CGO)
发表于: 3天前 205

[原创] 纯 Go 复刻浏览器 TLS HTTP/2 指纹:我写了一个可开源的库(JA3/JA4 逐字节一致,零 CGO)

3天前
205

作者:lingulingo  更新时间:2026
项目仓库:github.com/lingulingo/tlsprint

很多网站在你请求时会判断"你是不是真人浏览器"。这个判断往往不只是看 User-Agent,而是看你连 TLS 握手都发了什么——你的浏览器在 ClientHello 里带的密码套件顺序、扩展顺序、支持的曲线、签名算法,以及后面 HTTP/2 的 SETTINGS 顺序、WINDOW_UPDATE、伪头/请求头顺序每一家浏览器都不一样,这就是"TLS 指纹"。

业界用 JA3 / JA4 给它打指纹。给个真实例子:

如果你用 Go 默认的 net/http 发起请求,它的 TLS 指纹和浏览器完全不一样,很多站点看一眼就判定为"不是浏览器",直接给你 403 或跳到验证页。

而且大部分库的"HTTP/2 指纹"都没做——只把 TLS 做精确,HTTP/2 却走 Go 默认实现,两个加起来其实还是对不上真实浏览器的完整行为。

所以我写了 tlsprint,一个引擎无关的 Go TLS 指纹库

1. 查预设 + 算指纹

2. 直接拨号(自己写 HTTP)

3. 作为 HTTP 客户端(POST JSON 自动反序列化)

client 依赖我 fork 的 tlsprint/http2(基于 golang.org/x/net/http2)。我给它加了一个 Fingerprint 配置,把预设里的 HTTP/2 指纹直接写进连接序言和请求帧:

实测:服务端上报的 akamai_fingerprint 是:

和 Chrome 152 抓包完全一致;请求头顺序也和抓包逐字节一致。(有断言测试覆盖。)

我是这么验证"它能干活"的——用 chrome-152 + 一份新鲜的会话 cookie 请求一个被 Akamai 保护的电商页:

拿到真实商品页,不是验证页。这说明"连接层 + 指纹 + cookie"整条链路是通的。

tlsprint 想做的,是把"指纹"这件事做得标准、纯 Go、且真正的双向字节精确,把"数据层"和"引擎"解耦,让任何 Go 项目都能轻松接入。它不依赖 CGO、根模块零依赖、API 顺手,还带 47 个可校验的真实预设和一遍完整的真实站点验证。

如果你觉得有用,欢迎去 GitHub 点个 star ⭐、提 Issue 或 PR(新增指纹预设、更好的 HTTP/2 保真度、文档都可以):

声明:本文仅用于 TLS 协议研究与反爬对抗测试,请只对你有权测试的系统使用。项目为 MIT 协议,http2 子模块派生自 golang.org/x/net/http2(BSD-3-Clause,遵循上游)。

方案 做法 痛点
uTLS 自己造的 TLS 栈,能模仿浏览器 只有引擎,其他全要你自己写;指纹定义绑死在代码里
tls-client / go-bypasser 基于 uTLS 的 HTTP 客户端 依赖整个引擎;HTTP/2 层仍是 Go 默认,不逐字节
curl_cffi / pyhttpx C 语言 libcurl 封装 需要 CGO/原生库,跨平台编译头大
proteus 高层客户端 + 大预设 依赖 CGO + python 生成;数据层字符串型、丑陋
# Chrome 152 的 JA3(前两段就是密码套件 & 扩展顺序)
771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,
45-17613-13-43-10-0-51764-18-51-35-27-11-5-65281-16-65037-23,4588-29-23-24,0

# Akamai 的 HTTP/2 指纹
1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p
go mod init myapp
go get github.com/lingulingo/tlsprint/client@v1.0.0
package main

import (
    "fmt"
    tlsclient "github.com/lingulingo/tlsprint/client"
)

func main() {
    // 就像 curl_cffi 的 requests.get(url, impersonate="chrome")
    resp, err := tlsclient.Get("ed8K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6@1L8s2y4Q4x3X3g2H3k6h3g2@1i4K6u0W2N6%4y4Q4x3V1k6S2M7r3W2Q4x3V1k6S2L8r3H3`.",
        tlsclient.Impersonate("chrome-152"),       // 指纹:还支持 firefox-145 / safari-26-0-1 / chrome=最新
        tlsclient.Query("q", "tls fingerprint"),   // 查询参数
        tlsclient.Header("X-Api-Key", "secret"),   // 请求头(浏览器头会自动带)
    )
    if err != nil {
        panic(err)
    }
    fmt.Println(resp.StatusCode(), resp.Proto())   // 200 HTTP/2.0
    fmt.Println(resp.String())                     // 响应体(自动按 Content-Encoding 解压)
}
p := preset.MustBuiltin().Lookup("chrome-152")
fmt.Println(p.Key, p.Product, p.Version, p.UserAgent())

s := ja3.FromProfile(&p.TLS)        // 规范 JA3 字符串
fmt.Println(s, ja3.Hash(s))         // + 经典 md5 指纹 id
conn, err := tlsutls.DialByName(ctx, "tcp", "example.com:443", "chrome-152", nil)
defer conn.Close()
var result map[string]any
resp, err := tlsclient.Post("f91K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Z5N6s2c8H3j5X3W2F1i4K6u0W2L8%4u0Y4i4K6u0r3M7r3!0K6N6l9`.`.",
    tlsclient.Impersonate("chrome-152"),
    tlsclient.Body(map[string]any{"name": "tlsprint"}),
    tlsclient.Result(&result),
)
fmt.Println(result)
// 从预设自动生成的连接指纹
Settings        = []Setting{{HeaderTableSize, 65536}, {EnablePush, 0}, {InitialWindowSize, 6291456}, {MaxHeaderListSize, 262144}}
WindowUpdate    = 15663105
PseudoHeaderOrder = "m,a,s,p"      // :method,:authority,:scheme,:path
HeaderOrder     = [sec-ch-ua, sec-ch-ua-mobile, ..., priority]
Priority        = {Exclusive:true, Weight:255}
1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p

传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!

最后于 3天前 被灵谷编辑 ,原因:
收藏
免费 14
打赏
分享
最新回复 (7)
雪    币: 6
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
向大佬学习
3天前
0
雪    币: 2790
活跃值: (6901)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
3
感谢分享
3天前
0
雪    币: 158
活跃值: (5551)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
感谢分享。
3天前
0
雪    币: 112
活跃值: (9290)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
tql
3天前
0
雪    币: 236
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
如果 tlsprint 帮到了你,请给它点个 star
2天前
0
雪    币: 200
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
向大佬学习
2天前
0
雪    币: 220
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
6
3小时前
0
游客
登录 | 注册 方可回帖
返回