日拱一卒,守正出奇

细说 Charles 配置 HTTPS 代理的乱码问题

    计算机网络     HTTPS·SSL·TLS·Charles

  1. Charles HTTPS 代理配置
    1. SSL 代理设置
    2. 客户端证书安装
      1. PC 端证书安装
      2. 手机端证书安装
  2. 乱码的缘由 —— SSL 加密
  3. Charles 的破解之道

最近因工作需要,要用 Charles 来监听 HTTPS 的请求,然而好不容易按照网上的文章配置完成之后,却发现监听的内容居然是一坨乱码。随后进行了一个 SSL 代理配置,和手机证书的安装,才终于获取到了明文。虽然之前有了解 HTTPS 是使用大素数收到进行加密,也知道有一次非对称加密和对称加密,但是经过这次的配置发现对它的根本原理还不是很了解,于是专门研究了一下,才搞明白它的原委。

Charles HTTPS 代理配置

我们先开宗明义,把问题解决一下:要进行 HTTPS 代理配置,其实只需要两个步骤:

  1. 在代理端进行 SSL 代理设置;
  2. 在客户端进行证书安装。

SSL 代理设置

在 Charles 设置 SSL 代理,步骤为:

Proxy –> SSL Proxying Setting –> Enable SSL Proxying

之后便会看到下面的选框:

设置SSL代理

点击 Add,编辑 Loction,按照如下填写:

编辑Location

一路点 OK,这第一步就这样成了。

客户端证书安装

PC 端证书安装

假如代理的是 PC 端的 HTTPS 请求,需要在 PC 上信任 Charles 的证书,步骤为:

Help –> SSL Proxying –> Install Charles Root Certificate

选择 Charles 的证书,并信任此证书:

信任证书

手机端证书安装

在移动端安装证书,步骤为:

Help –> SSL Proxying –>Install Charles Root Certificate on a Mobile Device

之后会弹出这样一个对话框:

安装证书

按照上面的要求,在手机上配置好端口为 8888 的代理之后,访问 https://chls.pro/ssl 就可以下载证书并安装了。

实际上做完这两部,就可以在你的 PC 和移动设备上愉快的进行 HTTPS 的代理,并获取明文内容了(具体如何解决问题,也可以参考这篇文章);尽管到这一步就已经达到了实际使用的效果,但我还是产生了这样的疑问:为何进行 HTTPS 代理的配置需要配置 SSL,以及在客户端安装证书呢?之前截获的内容又为什么是乱码呢?

乱码的缘由 —— SSL 加密

其实稍微对 HTTPS 有点认知的童鞋,一开始就不应该对 HTTPS 截取的内容是乱码而感动吃惊:喵的这可是 HTTPS 啊,一个代理就能窃听到获明文内容,那也毫无安全性可言了吧。

那 HTTPS 到底是利用什么原理进行加密的呢?我们可以看到,上面的步骤中,配置 Charles 的第一步就是先配置一个 SSL 代理,实际上 HTTPS 的那个 S 也可以翻译为 HTTP over SSL/TLS,这个 SSL 正是 HTTP 加密依赖的基础协议。

SSL/TLS 是传输层安全协议,与其他应用层协议(如 HTTP/FTP 等)独立无关,也就是说,在应用层协议开始通信之前,SSL/TLS 协议就已经完成了相关的加密工作,后续协议传输的内容已经是加密数据了。所以其实 HTTP 还是那个 HTTP,但传输的内容早已变成天书,这也就是我们在用 Charles 进行代理的时候,看到一堆乱码的原因。

不过快播的审判员说的好:『文件加密了,你为什么不解密呢?』是啊,为什么经过 SSL/TLS 协议处理过的内容,不能够被解密呢?这里就涉及到 SSL 协议的基本原理,我们用写信,来模拟一下这个加密的过程:

  1. 小明和小王是一对好基友,但是远隔万水千山,只能通过写信来传递消息。俩人每天的信件都是通过邮递员小红来传递的,这俩人每天纸条上明文写着信息,小红也天天看的不亦乐乎,这就是 HTTP。
  2. 时间久了,两人发现不行,比如有时候会传递一些不和谐的内容,不希望小红这样的腐女看到;于是小明灵机一动,换成葬爱家族的杀马特火星文来进行通信;小王看后,心领神会。由于转换方式两人都知道,这就是对称加密技术
  3. 然而好景不长,小红勤学苦练,终于练成了火星文十级,又能看懂俩人加密的内容了。俩人必须要更换加密方式,但是更换的加密方式也只能通过小红来传递,所以这个加密的手段很难瞒住小红,这就是 HTTP 的不安全性。
  4. 正好小明是一位博学的哲♂学家,他立刻写了封信给小王:把你家储物间箱子的上那把挂锁寄过来!小王看后立刻拿出了那把 82 年的挂锁,把它打开并寄给了小明。这个锁大家都能看到,但只有小王有钥匙,这就是传说中的非对称加密,锁就是公钥,小王的钥匙就是私钥。
  5. 小明收到后,仔细研究了那把锁,上面烫着『隔壁老王』四个鎏金大字,正是王家祖传的锁,这就是验证服务端的数字证书
  6. 于是小明放心的把新的加密方式写在信中,放到盒子里,然后用锁锁上。由于小红没有钥匙,没法查看盒子里到底写了啥,只能原样送过去。小王收到后,用自己的钥匙打开了锁,获得了新的加密方式。这就完成了 SSL 协议的握手

当然,上面的过程描述的非常粗糙,小明和小王在互相寄锁的时候,还需传递随机数来辅助生产最终的加密方式(也是一个随机数,称之为 Premaster secret);有兴趣的兄贵们可以看看文末的参考文章。

Charles 的破解之道

那么问题就来了:Charles 作为一只小红,是怎么破解上述加密通信的呢?莫非她大力出奇迹,直接砸了锁?我们知道,要砸锁是不太现实的,这等于要对大素数的乘积进行因式分解,现阶段下还做不到;因此 Charles 就做了一件最简单的事情:伪装成小明(也就是中间人攻击)。

Charles 的官网上是这么说的:

Charles 作为一个中间人来进行 HTTPS 的代理,让我们检测到浏览器和 SSL web 服务端之间的明文通信。
Charles 把自己变成一个中间人来达到这一目的。你的浏览器是收不到服务端证书的,Charles 会用自己的根证书动态签发一张证书,然后 Charles 来接受服务端的证书,你的浏览器接受 Charles 的证书。

Charles 仍然通过 SSL 与服务端进行通信,但通信是通过浏览器到 Charles,然后在从 Charles 到服务器。

那么上文所说的根证书动态签发证书,指的是什么意思呢?这里就说到了证书的信任链体系,这是一个树状的结构,全球有为数不多的根证书颁发机构,授权二级证书颁发机构进行证书颁发;而只要用户信任了根证书,就会对其下属二级机构颁发的所有证书都予以信任。

证书颁发体系

上图可以看到 VeriSign 就是根证书颁发机构,而知乎的证书是由其二级证书颁发机构颁发的。由于操作系统里内置了对 VeriSign 的授信,因此知乎的地址栏才能有一把绿色的小锁。

因此 Charles 如果想对所有的域名颁发证书,必须要有一个根证书;用户信任了这个根证书,所有走 Charles 代理的 HTTPS 就都能被窃听了。

我们在用小红为例,复现一下这个场景:

  1. 小红拿到锁以后,先扣着不发,然后掏出了自己的锁寄给小明,这就是 Charles 签发了自己根证书;
  2. 小明一看这把锁不是正宗王家的,但是小红家的锁,似乎也可以相信,这就是信任了 Charles 的根证书
  3. 小明把加密方式写进去,然后用小红的锁锁起来了,小红打开之后研究了加密方式,发现两人是在用水星文进行交流,瞬间水星文也达到了十级,然后在换上小王的锁锁上了盒子,还给了小王;
  4. 小王毫不知情,之后俩人用水星文进行交流,但内容已经全被小红捕获到了。

搞明白这些之后,我们再来看一下,为什么要进行 Charles 的那两个配置呢?

  1. 设置 SSL 代理:因为默认 HTTP 请求走的是 80 端口,HTTPS 请求走的是 443 端口,不设置的话 Charles 仅会默认更改系统的 HTTP 代理,只有 HTTP 流量会走 Charles,而设置这个 HTTPS 的流量才会从这儿走;
  2. 安装 Charles 的根证书:根据信任链,只要安装一下 Charles 的根证书,之后 Charles 颁发的所有域名的证书都能被自动信任,因此 HTTPS 就都能被窃听了。

把证书的信任链翻译到锁上,等于小明会预先信任几个大厂生产的锁,比如只要是老王牌的锁,那我都相信,其他人也可以用这类锁来跟我要加密方式;Charles 等于创造了一个小红五金厂,把所有代理的请求都挂上了小红锁。那么 12306 其实跟小红一样,由于某些原因没有大厂申请一个锁,而是自己开了一个老铁五金厂,然后跟用户说:『相信我铁道部的老铁五金厂的锁吧,不然你就憋想回家!』

用户还能怎么办?只能含着泪点确认:『老铁,没毛病!』

参考文献

  1. 支付宝偷偷添加根证书 - 知乎
  2. 图解 SSL/TLS
  3. SSL/TLS 协议运行机制的概述
  4. 细说 CA 和证书
页阅读量:  ・  站访问量:  ・  站访客数: