通过Charles代理,我们能很轻易的抓取手机的Http请求,因为Http属于明文传输,所以我们能直接获取到我们要抓取的内容。但是Https内容本身就是加密的,这时我们会发现内容是加密的了。本文我们来讲述一下如何使用Charles抓取Https数据包及相关原理知识。
一、Https客户端和服务器端通信的基本流程
其实Charles就是这么做的,当配置了Charles之后,理论上所有的http/https请求数据都被拦截到了。看下面一张简化的中间人抓包的图:
二、如何使用Charles抓取Android设备发送的Https数据请求
注:为了保证最简单的方式实现,下面的Android设备默认都是Android 6.0及以下。
保证Android手机和抓取https请求的电脑在同一网络下,然后就可以开始进行抓取操作了。抓取主要分为三步,分别如下:
1.手机上导入Charles根证书
按照如下图所示操作即可:
2.设置Android 手机代理
按照如下图的配置设置是最简单的:
3.添加SSL代理设置
配置到此,我们就可以正常抓取到Https明文数据了。
三、Android 7.0及以上为何不能轻易抓取到Https请求的明文数据?
1. 问题分析
其实Charles上显示确实抓到了包,但是当我们看抓包的详细数据时会发现报错 You may need to configure your browser or application to trust the Charles Root Certificate. See SSL Proxying in the Help menu
。Charles说手机端没有信任Charles的根证书,但是我们手机上已经安装了Charles根证书了,为什么会这样?
原来在Android 7.0(API 24 ) ,有一个名为“Network Security Configuration”的新安全功能。这个新功能的目标是允许开发人员在不修改应用程序代码的情况下自定义他们的网络安全设置。如果应用程序运行的系统版本高于或等于24,并且targetSdkVersion>=24,则只有系统(system)证书才会被信任。所以用户(user)导入的Charles根证书是不被信任的。
2. Android 7.0 (api 24 ) 和 targetSdkVersion 对抓包的影响
这里要分两种情况:
- 抓自己开发的app的网络包
- 抓第三方app的网络包,比如微博客户端
这两种情况有什么区别的,第一种app是我们自己开发的,我们手里有源码,能够修改,能够做到像官方文档里面说的一样进行配置。第二种我们没有源码,要想做到像官方文档里面配置的话,只能反编译后,把配置文件添加进去然后重新打包,但是重新打包就会遇到很多坑,并不一定能成功,所以需要使用其他方式达到抓包目的。
引用官方文档一句话:默认情况下,来自所有应用的安全连接(使用 TLS 和 HTTPS 之类的协议)均信任预装的系统 CA,而面向 Android 6.0(API 级别 23)及更低版本的应用默认情况下还会信任用户添加的 CA 存储。应用可以使用 base-config(应用范围的自定义)或 domain-config(按域自定义)自定义自己的连接。
参考内容附录:
1. Android 系统各个版本上https的抓包:https://www.jianshu.com/p/3b4cd6fdd8a9
2. Html标签清除:http://www.jiniannet.com/Page/clearhtml
3. Unicode编码转换:http://tool.chinaz.com/tools/unicode.aspx