charles抓https包的原理和相关配置
这几天苦于charles抓https包的配置问题。虽然网上已经有很多文章讲解这个,但是没有一个轻松地解决了该问题。费了一番手脚解决之后,决定记一笔。希望能帮助一二。
首先让我们先来了解下https和charles抓包的原理。瓦力老师的这篇文章,非常详尽地解释了相关原理。过多的流程,不赘述。只讲下大概的思路:
http协议过程中传输的数据都是不加密的,很可能会被拦截窃取。为了解决这一点,出现了https。但是相应的加密方式也有两种1、对称加密 2、非对称加密。非对称加密效果好,但是性能损耗大(源于对称加密算法本身)。对称加密效果没有非对称加密效果好,但是性能损耗低。所以当前的https采用了一种折中的思路,即:服务器和客服端开始握手过程中,采用非对称加密得到一串加密字符串,往后的通信,都采用该加密字符串进行对称加密。
流程如下,主要就在3,4,5,6这四步。
i: 根据https协议,在3流程,服务器自身留有保密的私钥,将相应的公钥发送给客户端。这时候charles拦截了请求(因为charles与客服端在同一个局域网下,并且局域网的代理指向了charles,所以能够拦截。具体操作对应为 Charles安装与使用 中的 截取https通讯信息 小段)。
ii: 此时,charles能够拦截服务器返回的请求,但是却不能拦截客户端发出的请求,所以有了3,charles将自己的证书发送给客服端,客服端信任之后,请求才可以被charles拦截。同时,客服端此时只知道charles却不知道有服务器,客服端所有的请求都是通过请求charles,charles再转发给服务器实现的。客服端用charles给它的公钥进行数据加密。这样的加密字符串当然可以被charles解析(毕竟,是charles自己加的密,公钥**都是知道的。一切的原有都是因为没法获得服务器的私钥,所以要通过这样子的形式来欺骗~~~),获得加密字符串。再用服务器的公钥加密之后,将加密字符串发送给服务器。服务器接收到该字符串,再用公钥解密,也获得了相应的加密字符串,通知一下客户端。这样子,客户端和服务器的握手流程就全部完成了,他们都不知道其中有这么一个charles在使坏。。。
原理就讲到这里。
接下来我们来讲讲相关的配置,具体的配置 “Charles安装与使用 ”已经讲得很好了。只讲一些细节,自己遇到的坑。
1、IOS 证书安装完成之后,还需要对证书添加相关的信任操作。 General > About > Certificate Trust Settings
2、Andriod 的话,相应得更麻烦一些。还需要添加相应的配置文件到app目录下。
增加 res/xml/network_security_config.xml 到app下,
<network-security-config> <debug-overrides> <trust-anchors> <!-- Trust user added CAs while debuggable only --> <certificates src="user" /> </trust-anchors> </debug-overrides> </network-security-config>然后在应用程序清单中添加对该文件的引用,如下:
<?xml version="1.0" encoding="utf-8"?> <manifest ... > <application android:networkSecurityConfig="@xml/network_security_config" ... > ... </application> </manifest>
官网说明:https://www.charlesproxy.com/documentation/using-charles/ssl-certificates/
好了,大体就是这样子了。android配置流程要麻烦很多,我的是ios,所以也没有实践过,估计还会有挺多坑的。