实现原理:JA3 / JA3S 指纹
对应代码:
pkg/ja3.go· 入口JA3Scan(target)
JA3 是客户端指纹(看 ClientHello),JA3S 是服务端指纹(看 ServerHello)。两者都用 MD5 哈希特定字段的拼接串。本页讲字段顺序、精确 ID 列表与一个重要局限。
JA3:客户端指纹
原始串 5 个字段,顺序固定,字段内 , 分隔、字段间也 , 分隔:
TLSVersion, CipherSuites, Extensions, EllipticCurves, PointFormats精确字段取值(反映 Go 客户端发出的 Hello)
CipherSuites(getStandardClientCipherIDs L179-196,11 项):
| 类别 | 套件 ID |
|---|---|
| TLS 1.3 | 0x1301, 0x1302, 0x1303 |
| TLS 1.2 ECDHE | 0xC02B, 0xC02F, 0xC02C, 0xC030, 0xCCA9, 0xCCA8 |
| TLS 1.2 RSA | 0x009C, 0x009D |
Extensions(L112-122,9 项):
| ID | 名称 |
|---|---|
0x0000 | server_name |
0x000d | signature_algorithms |
0x0010 | ALPN |
0x0017 | extended_master_secret |
0x0023 | session_ticket |
0x002b | supported_versions |
0x002d | psk_key_exchange_modes |
0x0033 | key_share |
0xff01 | renegotiation_info |
EllipticCurves(L126-131,4 项):0x001d(X25519) / 0x0017(P-256) / 0x0018(P-384) / 0x0019(P-521)
PointFormats:仅 0x00(uncompressed)
TLSVersion:取 state.Version 数字(如 771=0x0303)
JA3S:服务端指纹
原始串 3 个字段:
TLSVersion, CipherSuite, ExtensionsJA3S 扩展累加条件与 ID:
| 扩展 ID | 名称 | 累加条件 |
|---|---|---|
16 (0x0010) | ALPN | state.NegotiatedProtocol != "" |
23 (0x0017) | session_ticket | state.DidResume(会话恢复) |
43 (0x002b) | supported_versions | state.Version == TLS1.3 (0x0304) |
65281 (0xff01) | renegotiation_info | 无条件追加 |
JA3S 用 - 连接扩展
JA3S 的扩展字段用 - 连接(如 16-23-43),区别于 JA3 的 , 连接——在哈希前区分服务端与客户端的扩展列表格式。
JA3Scan 配置
config := &tls.Config{
NextProtos: ["h2", "http/1.1"],
CurvePreferences: [X25519, P256, P384, P521],
MinVersion: TLS1.2,
InsecureSkipVerify: true,
}失败时 result.Error 填字符串、返回 *JA3Result, nil(不返回 error)。
关键局限:Go 不暴露原始 ClientHello
Go 的 tls.ConnectionState 不暴露原始 ClientHello 字节,cert-skills 的 JA3 是从客户端 tls.Config 重建的——它反映"我们用什么 Hello 去连",而非"目标客户端用什么 Hello"。
这意味着:
- JA3 用来识别我们自己的客户端画像(对服务端没用)
- JA3S 才是真正对服务端画像(看服务器回了什么)
Go 标准库的限制(非 bug)
这不是 cert-skills 的 bug,而是 Go 标准库的限制:tls.ConnectionState 不暴露原始 ClientHello。要采任意客户端的 JA3,需在中间人/网络层抓包解析原始 ClientHello,超出 CLI 工具范围。JA3S 才是真正对服务端画像。
输出
type JA3Result struct {
JA3Hash string // 32 字符
JA3Raw string // 原始拼接串
JA3SHash string // 32 字符
JA3SRaw string
TLSVersion string
CipherSuite string
ALPN string
Error string
}用途对比
| 指纹 | 画像对象 | cert-skills 场景 |
|---|---|---|
| JA3 | 客户端 | 有限——反映自身客户端配置 |
| JA3S | 服务端 | 主用——服务端 Hello 画像 |
| JARM | 服务端 | 主用——更全面的服务端画像(10 探针) |
测绘里 JA3S + JARM 互补:JARM 用 10 个探针看响应差异,JA3S 看实际协商出的 ServerHello。