如何在Java桌面应用中拦截所有HTTP请求以用于调试?
我之前也踩过Java程序抓包的坑,尤其是桌面应用,明明按文档配置了还是抓不到,给你分享几个亲测有效的排查和解决步骤:
强制JVM使用Fiddler代理
Java不会自动继承系统代理,哪怕你开了Fiddler的系统代理也白搭。直接在IntelliJ的Run/Debug配置里加VM参数:-Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=8888 -Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=8888 -Djavax.net.ssl.trustStore="你的Fiddler证书路径/FiddlerRoot.p12" -Djavax.net.ssl.trustStorePassword=changeit记得把证书路径换成你本地的实际路径,默认密码是
changeit。如果是打包后的程序,把这些参数加到启动脚本里就行。确认证书导入到了正确的密钥库
很多人踩坑是因为把证书导入了用户目录的.keystore,但Java默认用的是JRE自带的cacerts密钥库!比如JDK11的路径大概是C:\Program Files\Java\jdk-11.x.x\lib\security\cacerts,密码同样是changeit。用这个命令导入:keytool -import -alias FiddlerRoot -keystore "你的JDK路径/lib/security/cacerts" -file "你的Fiddler证书路径/FiddlerRoot.cer"导入后用下面的命令验证是否成功:
keytool -list -keystore "你的JDK路径/lib/security/cacerts" -alias FiddlerRoot能查到条目就说明导入对了。
检查代码里的硬编码代理或证书绕过逻辑
看看你的API调用代码(比如用OkHttp、HttpClient的地方),有没有硬设代理或者自定义SSL信任逻辑?比如:// 硬编码其他代理 Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("xxx.xxx.xxx.xxx", 8080)); // 绕过证书校验 TrustManager[] trustAllCerts = new TrustManager[]{...};如果有,要么注释掉,要么把代理改成Fiddler的
127.0.0.1:8888。Wireshark抓包的额外配置
如果用Wireshark抓HTTPS,得配置SSL解密:把Fiddler的证书导入Wireshark,然后在Wireshark设置(Edit > Preferences > Protocols > SSL)里添加RSA密钥日志文件(Fiddler可以通过Tools > Options > HTTPS > Export Keys导出)。另外,如果Java用了HTTP/2,Wireshark支持可能不好,加VM参数强制用HTTP/1.1:-Djdk.httpclient.http2.disable=trueIntelliJ的JDK版本混淆问题
如果你电脑装了多个JDK,IntelliJ可能没用到你导入证书的那个版本。去File > Project Structure > Project里确认Project SDK是你配置过的JDK,再检查Modules里的SDK是否一致。
内容的提问来源于stack exchange,提问作者ivanlirchev

