完美解决安卓7.0及7.0以上的机子Charles不能抓取 ht

2023-03-30  本文已影响0人  笔头还没烂

一、先摆出问题:
如题,今天遇到了一个安卓手机无法抓取 https 请求的问题,提示:Client SSL handshake failed: An unknown issue occurred processing the certificate(certificate_unknown)

如下图所示: 02报错信息.png

于是我重新检查了一下环境配置:

排查了一圈,没发现哪里有问题。要是换作是 iOS(操作步骤跟上面的大同小异),都到这一步了肯定是没问题的。我重新打开 安卓的 app 再尝试抓包,发现还是不行。于是我重启了安卓手机,再尝试抓包,还是不行。摸不着头脑的我只能开始在网上寻找答案。

二、后面终于找到了解决方案:

  1. 前提:在手机端和电脑端都必须安装 https 的安全证书;

  2. 配置:打测试包时,项目设置默认信任所有证书(系统+用户)
    (1) 在工程 res-xml 目录中创建一个名为 network_security_config.xml 的文件,文件内容如下:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" overridePins="true" />
            <certificates src="user" overridePins="true" />
        </trust-anchors>
    </base-config>
</network-security-config>

(2) 在 AndroidManifest 里的标签中,添加如下代码:

android:networkSecurityConfig="@xml/network_security_config"

重新打包项目,然后抓包,即成功了。
你以为到这就结束了?然而并没有。

三、我还是有个疑问,上面的例子只适合能够修改源码并能重新打包或者是真机调试的情况。如果是之前已经打好的包突然某个接口网络请求出问题只能采取抓包的方式来解决,并且之前并没有添加上面的代码的情况,那又该怎么呢?
接下来要敲重点了:Android 7.0及7.0以上的机子改变了安全策略,默认不信任用户添加到系统的 CA 证书:

To provide a more consistent and more security experience accross the Android ecosystem,beginning with Android Nougat, compatible devices trust only the standardized system CAs maintained in AOSP.
翻译:
为了在Android生态系统中提供更一致、更安全的体验,从Android Nougat开始,兼容设备只信任AOSP中维护的标准化系统CA。

也就是说对基于 SDK24 及以上的 App 来说,即使你在手机上安装了抓包工具的证书也无法抓取 https 请求。

解决方案:
将抓包工具的证书添加到系统证书中!效果如下图所示:

将抓包工具的证书添加到系统证书中.png

实践步骤:

  1. 需要先获取你的安卓测试机 root 权限。我用的是红米手机,获取 root 权限操作如下:设置 ---> 授权管理 --> 开启ROOT权限 即可。之后手机会重启,重启之后即可成功 root 。
  2. 通过 电脑端的 Charles 拿到后续要安装到手机上的证书,并通过 openssl x509 -subject_hash_old -in 命令计算出它的哈希值。并将证书重命名为 哈希值.0 或者哈希值.1 。
openssl x509 -subject_hash_old -in 
  1. root 成功的安卓测试机连接电脑。我这里用是 mac 笔记本。接下来是mac 通过终端来操作:
cd /Users/pilipala/Downloads; clear; pwd
安卓系统的安全证书是在 /system/etc/security/cacerts 目录下的,终端输入 adb shell ,打开目录就能看到这些证书,如下图所示: 安卓系统的安全证书.png

我们最终目标是要将安装到手机端的证书添加到该目录下。而在这之前,我们得先将证书发送到手机端的 sdcard 的 Download 目录,再将证书从手机端的 sdcard 的 Download 目录复制到安卓系统的安全证书目录。

接着输入 adb push 命令将证书推给手机端的 sdcard 的 Download 目录。命令如下:

adb push f050a275.1 /sdcard/Download
注意看终端的提示,此时终端很快会提示你有一个文件被 pushed,即 push 成功。如下图所示: image.png
  1. 这一步很关键,需要将 /sdcard/Download 目录下的证书复制到系统证书的所在目录。命令如下:
cp /sdcard/Download/f050a275.1 /system/etc/security/cacerts/
然而我复制的时候提示我证书是一个 ReadOnly 文件。如下图所示: 复制时报错.png

我通过测试,发现关闭手机安全验证机制的方案是可以解决的,命令如下:

adb root
adb disable-verity
adb reboot //此时手机会重启,这时候不要拔插数据线

手机重启后,再次执行上面的 cp 命令,如果终端没有任何提示,即复制成功,看到胜利的曙光了。

  1. 接着,赋予证书执行的权限。
chmod 644 /system/etc/security/cacerts/f050a275.1
  1. 最后重启手机即可。

到这里,再打开手机设置 --> 更多设置 --> 系统安全 --> 信任的凭据 --> 系统,就能看到抓包工具的证书已经被我们成功添加进来了。默认是开启信任的。如果没有,打开信任即可。

再重新抓包,就能发现 https 的请求也能抓取到了。

四、写在最后

  1. 证书重命名那一块,一般会将证书重命名为:哈希值.0,如果安卓系统的安全证书目录下已经存在相同哈希值的证书,可以将证书的后缀名重命名为 .1 。再将证书复制到安卓系统的安全证书目录下。
  2. 其他品牌的手机(如 vivo等)我没试过,不过操作步骤应该是差不多的。

以上,感谢阅读!

上一篇 下一篇

猜你喜欢

热点阅读