1.需求

在springboot业务项目中能够拿到协议层的指纹数据。关于springboot获取JA3的相关文章网上很少见到,经过几天的摸索有了阶段性的成果,本文通过tomcat方式来获取指纹并将指纹数据与request进行绑定,传递到业务层中。
关于JA3指纹讲解请参考:通过 JA3(S) 实现 TLS 指纹识别

2.从tomcat中获取ja3指纹

①找到springboot对应版本的Tomcat,并下载源码(springboot内置的tomcat和apache提供的tomcat有一些区别)

#springboot内嵌tomcat
wget https://repo1.maven.org/maven2/org/apache/tomcat/embed/tomcat-embed-core/9.0.43/tomcat-embed-core-9.0.43-sources.jar

# 官方tomcat
wget https://codeload.github.com/apache/tomcat/tar.gz/refs/tags/9.0.43 -O tomcat-9.0.43.tar.gz

②使用idea编译Tomcat源码
参考
③Tomcat配置https
修改conf/server.xml文件,修改内容:

<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS"
               keystoreFile="6072302_www.bbmax.cc.jks"
               keystorePass="password"/>

<!--注释内容-->
<!--    <Connector port="8080" protocol="HTTP/1.1"-->
<!--               connectionTimeout="20000"-->
<!--               redirectPort="8443" />-->

④下载ja3_3java源码

git clone https://github.com/lafaspot/ja3_4java.git

并将代码复制到tomcat项目中
⑤新增test.jsp测试页面(官方Tomcat)
webapps->ROOT->目录下test.jsp文件,文件内容

<%@ page import="java.util.Enumeration" %>
<%
    StringBuilder sb = new StringBuilder();
    Enumeration<String> e = request.getHeaderNames();
    while (e.hasMoreElements()) {
        String name = e.nextElement();
        String value = request.getHeader(name);
        sb.append("name=");
        sb.append(name);
        sb.append(",value=");
        sb.append(value);
        sb.append("</br>");
    }
    out.println(sb.toString());
%>

⑥修改Tomcat源码
类:org.apache.tomcat.util.net.jsse.JSSESSLContext

找到createSSLEngine()方法,将return context.createSSLEngine();替换成return new JA3SSLEngineWrapper(context.createSSLEngine());

类:org.apache.tomcat.util.net.SocketWrapperBase

新增字段:public String ja3Signature;

类:org.apache.tomcat.util.net.NioEndpoint

找到代码handshake = socketWrapper.getSocket().handshake(event == SocketEvent.OPEN_READ, event == SocketEvent.OPEN_WRITE);在代码下一行新增内容:
SecureNioChannel secureNioChannel = (SecureNioChannel) socketWrapper.getSocket();
String ja3Signature = ((JA3SSLEngineWrapper) secureNioChannel.sslEngine).getJa3Signature();
socketWrapper.ja3Signature = ja3Signature;

类:org.apache.coyote.http11.Http11Processor

找到代码getAdapter().service(request, response);,在代码上一行新增内容:
MimeHeaders mimeHeaders = request.getMimeHeaders();
MessageBytes messageBytes = mimeHeaders.addValue("ja3Signature");
messageBytes.setString(socketWrapper.ja3Signature);

⑥浏览器访问https://localhost/test.jsp,查看是否存在ja3Signatureheader请求头(官方Tomcat)

3.将要ja3相关的class添加到tomcat.jar中(内嵌Tomcat)

找到springboot内嵌的Tomcat包,将jar包copy到源码项目的target/classes目录下,执行以下命令将class添加到jar中:

# 找到tomcat.jar,执行jar添加.class命令
jar -uf tomcat-embed-core-9.0.43.jar com/lafaspot/ja3_4java/JA3Constants.class
jar -uf tomcat-embed-core-9.0.43.jar com/lafaspot/ja3_4java/JA3SSLEngineWrapper.class
jar -uf tomcat-embed-core-9.0.43.jar com/lafaspot/ja3_4java/JA3SSLContextSpi.class
jar -uf tomcat-embed-core-9.0.43.jar com/lafaspot/ja3_4java/JA3Signature.class

jar -uf tomcat-embed-core-9.0.43.jar org/apache/tomcat/util/net/jsse/JSSESSLContext.class
jar -uf tomcat-embed-core-9.0.43.jar org/apache/tomcat/util/net/SocketWrapperBase.class
jar -uf tomcat-embed-core-9.0.43.jar org/apache/tomcat/util/net/NioEndpoint.class
jar -uf tomcat-embed-core-9.0.43.jar org/apache/tomcat/util/net/NioEndpoint\$SocketProcessor.class
jar -uf tomcat-embed-core-9.0.43.jar org/apache/coyote/http11/Http11Processor.class

到这一步可以将tomcat-embed-core-9.0.43.jar放到业务项目使用,业务项目中国可以通过request的Header中获取大ja3的指纹数据。
参考资料:
谈谈 Tomcat 请求处理流程
通过 JA3(S) 实现 TLS 指纹识别

最后修改:2022 年 09 月 03 日
如果觉得我的文章对你有用,请随意赞赏