为什么要为JDK安装Charles证书
众所周知,https就是为了防止中间过程被拦截从而导致数据泄密的。若强行加入Charles代理,数据被解密后再被其重新加密,数据已经被“破坏”,客户端从而拒绝建立连接或解析内容。
以往想要在浏览器或者移动设备环境中抓取到调用了哪些https接口,需要向系统或者移动设备中安装Charles根证书,并添加信任。具体操作方式为:
但是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代理,在代理抓取到的请求记录中,即可看到自己的请求是否符合要求。