You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js服务端如何读取Hello数据包生成JA3指纹?

JA3/JA3S NPM库推荐及Node.js实现指南

一、现成的NPM库

直接用这些库可以快速实现JA3/JA3S指纹生成,不用自己造轮子:

  • ja3:最常用的实现,支持从TLS连接提取并生成JA3/JA3S哈希,API简单,直接集成到Node.js服务端即可。
  • tls-parser:通用TLS数据包解析库,能解析Client/Server Hello的所有字段,适合需要自定义指纹逻辑的场景,你可以基于它的解析结果拼接JA3字符串。
  • node-ja3:轻量版JA3实现,专注于核心指纹生成,适合资源有限的轻量服务端。

二、自行开发的Node.js实现思路

完全不需要依赖Python库,Node.js原生tls模块就能搞定,核心是在TLS握手阶段拦截并解析Client Hello数据包:

1. 拦截Client Hello数据包

在TLS服务器建立连接的初期,还没完成握手前,捕获原始的网络数据。可以通过监听connection事件(此时是原始TCP连接)来获取数据,判断是否为Client Hello包后再交给TLS层处理:

const tls = require('tls');
const fs = require('fs');
const crypto = require('crypto');

const server = tls.createServer({
  key: fs.readFileSync('server-key.pem'),
  cert: fs.readFileSync('server-cert.pem')
}, (socket) => {
  socket.end('Hello!\n');
});

// 拦截原始TCP连接,捕获Client Hello
server.on('connection', (rawSocket) => {
  let buffer = Buffer.alloc(0);
  const onData = (data) => {
    buffer = Buffer.concat([buffer, data]);
    // 检查是否是Client Hello:TLS记录类型22(握手),握手消息类型1(Client Hello)
    if (buffer.length >= 5 && buffer[0] === 22 && buffer[5] === 1) {
      // 解析Client Hello并生成JA3哈希
      const ja3Components = parseClientHello(buffer);
      const ja3String = `${ja3Components.version},${ja3Components.cipherSuites.join('-')},${ja3Components.extensions.join('-')},${ja3Components.ecCurves.join('-')},${ja3Components.ecPointFormats.join('-')}`;
      const ja3Hash = crypto.createHash('md5').update(ja3String).digest('hex');
      console.log('JA3 Hash:', ja3Hash);

      // 停止监听数据,把连接交给TLS层继续握手
      rawSocket.removeListener('data', onData);
      server._connections[rawSocket._handle.fd] = rawSocket;
      server._tlsWrap.handshake(rawSocket);
    }
  };
  rawSocket.on('data', onData);
});

server.listen(443, () => console.log('TLS server running on port 443'));

2. 解析Client Hello的核心逻辑

按照TLS协议结构解析缓冲区,提取JA3需要的字段:

function parseClientHello(buffer) {
  // 跳过TLS记录头(5字节)和握手消息头(4字节),直接到Client Hello内容
  let offset = 9;
  // 读取TLS版本(2字节,转十进制)
  const version = buffer.readUInt16BE(offset);
  offset += 2;

  // 跳过随机数(32字节)和会话ID(1字节长度 + 对应长度内容)
  offset += 32;
  const sessionIdLen = buffer.readUInt8(offset);
  offset += 1 + sessionIdLen;

  // 读取密码套件(2字节长度,然后每个套件2字节)
  const cipherSuiteLen = buffer.readUInt16BE(offset);
  offset += 2;
  const cipherSuites = [];
  for (let i = 0; i < cipherSuiteLen; i += 2) {
    cipherSuites.push(buffer.readUInt16BE(offset + i).toString());
  }
  offset += cipherSuiteLen;

  // 跳过压缩方法(1字节长度 + 对应长度内容)
  const compressMethodLen = buffer.readUInt8(offset);
  offset += 1 + compressMethodLen;

  // 读取扩展列表(2字节长度,然后每个扩展:2字节类型 + 2字节长度 + 内容)
  const extensionsLen = buffer.readUInt16BE(offset);
  offset += 2;
  const extensions = [];
  const ecCurves = [];
  const ecPointFormats = [];
  let extOffset = offset;
  while (extOffset < offset + extensionsLen) {
    const extType = buffer.readUInt16BE(extOffset);
    extensions.push(extType.toString());
    const extDataLen = buffer.readUInt16BE(extOffset + 2);
    extOffset += 4;

    // 提取椭圆曲线扩展(类型10)
    if (extType === 10) {
      const ecLen = buffer.readUInt16BE(extOffset);
      extOffset += 2;
      for (let i = 0; i < ecLen; i += 2) {
        ecCurves.push(buffer.readUInt16BE(extOffset + i).toString());
      }
    }
    // 提取椭圆曲线点格式扩展(类型11)
    else if (extType === 11) {
      const ecFormatLen = buffer.readUInt8(extOffset);
      extOffset += 1;
      for (let i = 0; i < ecFormatLen; i++) {
        ecPointFormats.push(buffer.readUInt8(extOffset + i).toString());
      }
    } else {
      extOffset += extDataLen;
    }
  }

  return {
    version: version.toString(),
    cipherSuites,
    extensions,
    ecCurves,
    ecPointFormats
  };
}

3. 生成JA3哈希

把解析得到的字段按规则拼接成字符串,再做MD5哈希就是最终的JA3指纹。JA3S的实现逻辑类似,只是解析Server Hello数据包即可。

三、关键注意事项

  • 处理数据包时要注意粘包问题,可以通过记录头的长度字段判断是否捕获到完整的Client Hello包。
  • 拦截数据后必须把连接交还给TLS层,否则握手会失败。
  • 不同TLS版本的Client Hello结构略有差异,需要兼容TLS 1.0/1.1/1.2/1.3(JA3对TLS 1.3的支持需要调整字段提取逻辑)。

内容的提问来源于stack exchange,提问作者charnould

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 18:47:14