烂笔头笔记:为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代理,在代理抓取到的请求记录中,即可看到自己的请求是否符合要求。

相关推荐
源码技术栈2 分钟前
springboot支持多家机构共同使用的java门诊信息管理系统源码
java·源码·诊所·医保·门诊管理·医生工作站·处方
Empty_7772 分钟前
K8S-Job & Cronjob
java·linux·docker·容器·kubernetes
AI云原生1 小时前
在 openEuler 上使用 x86_64 环境编译 ARM64 应用的完整实践
java·运维·开发语言·jvm·开源·开源软件·开源协议
科普瑞传感仪器1 小时前
航空航天制造升级:机器人高精度力控打磨如何赋能复合材料加工?
java·前端·人工智能·机器人·无人机·制造
q_19132846951 小时前
基于SpringBoot2+Vue2的宠物上门服务在线平台
java·vue.js·spring boot·mysql·宠物·计算机毕业设计·源码分享
CoderYanger1 小时前
动态规划算法-两个数组的dp(含字符串数组):42.不相交的线
java·算法·leetcode·动态规划·1024程序员节
小蝙蝠侠1 小时前
async-profiler 火焰图宽度是否可信?哪些情况下会误导?(深度解析)
java·性能优化
IT_Octopus1 小时前
java多线程环境下 安全地初始化缓存(避免缓存击穿),同时兼顾性能 的双重检查锁方案
java·spring·缓存
Li_7695321 小时前
Spring Cloud —— SkyWalking(四)
java·spring cloud·skywalking