烂笔头笔记:为JDK安装Charles证书,让你的请求能够像在浏览器中那样被抓包

为什么要为JDK安装Charles证书

众所周知,https就是为了防止中间过程被拦截从而导致数据泄密的。若强行加入Charles代理,数据被解密后再被其重新加密,数据已经被"破坏",客户端从而拒绝建立连接或解析内容。
发起请求并加密 拆包解密再加密 加密 拆包解密再加密 浏览器/移动设备 Charles代理 接口服务端

以往想要在浏览器或者移动设备环境中抓取到调用了哪些https接口,需要向系统或者移动设备中安装Charles根证书,并添加信任。具体操作方式为:
安装 信任区 安装 信任 网络库 中间根证书 浏览器 系统证书管理 移动设备 证书信任 APP

但是JDK或者JVM有点特殊,它有它自己的证书管理体系(keystore),按照以往的方式安装并信任Charles根证书是不起作用的。

保存Charles根证书

在菜单Help一栏中找到SSL Proxying项目,选择"Save Charles Root Certificate",如下图所示:

找一个目录,输入文件名,将其保存。这里注意选择文件类型为:Base 64 encoded certificate(.pem)格式的:

将Charles根证书添加至JDK(JVM)的证书信任区(keystore)

打开命令终端(Linux/macOS)或者命令提示符(Windows)。将当前目录切换至JAVA_HOME。
注意:如果你的系统中有多个版本的JDK(JVM),或者重新安装了JDK(JVM),则需要重复本步骤

然后进入相对的这个目录(Linux/macOS):

jre/lib/security

或者(Windows)

jre\lib\security

执行如下命令(以Windows环境为例,可能需要管理员权限):

keytool -import -alias charles -keystore cacerts -file d://docs/cert//charles_root_certificate.pem

JDK(JVM)默认的keystore是一个名为"cacerts"的文件。命令中给新导入的根证书取了一个别名,叫做:"charles"。最后一个参数为上一步保存的Charles根证书完整文件名

执行过程中会提示用户输入"输入密钥库口令",默认为空

执行后会读取Charles根证书的基本信息。大概内容如下:

所有者: C=NZ, ST=Auckland, L=Auckland, O=XK72 Ltd, OU=https://charlesproxy.com/ssl, CN="Charles Proxy CA (31 May 2024, MYPCNAME)"
发布者: C=NZ, ST=Auckland, L=Auckland, O=XK72 Ltd, OU=https://charlesproxy.com/ssl, CN="Charles Proxy CA (31 May 2024, MYPCNAME)"
序列号: 18fcd412aae
生效时间: Thu May 30 14:05:51 CST 2024, 失效时间: Fri May 30 14:05:51 CST 2025

随后会询问用户:"是否信任此证书? [否]: ",此处输入:Y

当看到"证书已添加到密钥库中"这样的提示时,说明已经添加成功。

验证根证书

根证书导入完毕,以后如何验证是否添加了该证书呢?仍然可以使用keytool工具进行读取。

跳转至上一步中介绍到的目录,使用如下命令(Linux/macOS):

keytool -list -keystore cacerts | grep charles

或者(Windows)

keytool -list -keystore cacerts | findstr charles

工具提示用户输入keystore的密码,默认为空。

若看到类似如下内容即说明已经安装:

charles, 2024-6-18, trustedCertEntry,

经验分享,在IDE中如何结合Charles调试https接口调用

在系统对接过程中,往往会出现一些非常低级的错误。例如,对方要求POST方式以表单形式提交数据,结果以POST JSON body方式提交了。那么如何能够快速验证自己写的代码是否正确呢?

打开charles后(假设本地IP:192.168.100.1,代理端口为:8888,并且启用了SSL代理),回到IDE,在待调试项目的启动入口处修改JVM选项,增加如下JVM参数:

-Dhttp.proxyHost=192.168.100.1 -Dhttp.proxyPort=8888 -Dhttps.proxyHost=192.168.100.1 -Dhttps.proxyPort=8888

注意:只设置http.proxyHost和http.proxyPort是无法抓取到https请求的

这样当程序调用了外部https协议的接口时,请求就会经过Charles代理,在代理抓取到的请求记录中,即可看到自己的请求是否符合要求。

相关推荐
m0_571957587 分钟前
Java | Leetcode Java题解之第218题天际线问题
java·leetcode·题解
一个小浪吴啊17 分钟前
Java SpringBoot MongoPlus 使用MyBatisPlus的方式,优雅的操作MongoDB
java·spring boot·mongodb
InterestingFigure20 分钟前
Java 使用sql查询mongodb
java·开发语言·数据库·sql·mongodb
Janebook21 分钟前
Java技术栈总结:Spring框架篇
java·开发语言
香蕉你个不呐呐63528 分钟前
io流 多线程
java·开发语言
W Y38 分钟前
【架构-20】死锁
java·数据库·架构··死锁·银行家算法
捕风捉你41 分钟前
状态模式在金融业务中的应用及其框架实现
java·开发语言·状态模式
Cloud-Future44 分钟前
Spring cloud 中使用 OpenFeign:让 http 调用更优雅
java·spring cloud·openfeign·feign
Synaric1 小时前
Android与Java后端联调RSA加密的注意事项
android·java·开发语言
Tech Synapse2 小时前
java 如何暴露header给前端
java·开发语言·前端