mitmproxy 的 Android CA 证书
自 Android 7 起,应用会忽略用户提供的证书
自 Android 7 起,应用会忽略用户提供的证书,除非它们被配置为使用这些证书。由于大多数应用不会明确选择使用用户证书,我们需要将 mitmproxy CA 证书放入系统证书存储中,以避免必须为每个想要监控的应用打补丁。
注意:应用可以决定忽略系统证书存储并维护自己的 CA 证书。在这种情况下,你必须对该应用打补丁。
1. 先决条件
- 已安装 Android Studio / Android SDK(已在 Linux 64 位版本 4.1.3 上测试)
- 已创建 Android 虚拟设备(AVD)。设置文档可在此处获取
- AVD 生产构建(标有“Google Play”的构建)会阻止你使用
adb root。如果你需要安装 Google Play,则需要使用 Magisk 方法 - AVD 的代理设置已配置为使用 mitmproxy。文档在此处
Android SDK 中的
emulator和adb可执行文件已添加到$PATH变量中- emulator 在 Linux 系统上通常位于
/home/<your_user_name>/Android/Sdk/emulator/emulator - adb 在 Linux 系统上通常位于
/home/<your_user_name>/Android/Sdk/platform-tools/adb 我将这些行添加到了我的
.bashrc中:export PATH=$PATH:$HOME/Android/Sdk/platform-tools export PATH=$PATH:$HOME/Android/Sdk/emulator
- emulator 在 Linux 系统上通常位于
Mitmproxy CA 证书已创建
- 在 Linux 系统上通常位于
~/.mitmproxy/mitmproxy-ca-cert.cer - 如果该文件夹为空或不存在,请运行 mitmproxy 以生成证书
- 在 Linux 系统上通常位于
2. 重命名证书
Android 中的 CA 证书按其哈希值命名存储,扩展名为 0(例如:c8450d0d.0)。有必要计算出你的 CA 证书的哈希值,并将其复制到一个以该哈希值作为文件名的文件中。否则 Android 将忽略该证书。默认情况下,mitmproxy CA 证书位于此文件中:~/.mitmproxy/mitmproxy-ca-cert.cer
说明
进入你的证书文件夹:
cd ~/.mitmproxy/生成哈希并复制证书:
hashed_name=`openssl x509 -inform PEM -subject_hash_old -in mitmproxy-ca-cert.cer | head -1` && cp mitmproxy-ca-cert.cer $hashed_name.0
3. 将证书插入系统证书存储
现在我们必须将我们的 CA 证书放入 Android 文件系统中位于 /system/etc/security/cacerts/ 的系统证书存储内。默认情况下,/system 分区以只读方式挂载。以下步骤描述了如何获得对 /system 分区的写入权限,以及如何复制上一步中创建的证书。
使用 Magisk 时的说明
如果你想使用生产构建(标有“Google Play”;就是那些安装了 Google Play 的构建),你可以使用 Magisk 在你的 AVD 中获取 root 权限。Magisk 允许在你的 Android 设备或模拟器上获得 root 权限。
有关在 AVD 上安装 Magisk 的说明,请参见此处。
注意:说明中说要启动你的 AVD。此时不要向 mitmproxy 提供 -http-proxy 指令。完成后,你的模拟器将允许 root。你可以通过运行终端模拟器并输入 su 来检查这一点。Magisk 应该会询问你是否要向该程序授予 root 权限。授予后,输入 whoami 将显示 root。
然而,在你安装 Magisk 后,你不能再使用 -writable-system 启动模拟器。这会导致启动循环。(使用 -show-kernel 启动你的 AVD 以查看错误。)但是你可以通过将 mitmproxy 证书放入 Magisk 模块并安装该模块来安装它。Magisk 将在启动期间负责将你的证书复制到 /system/etc/security/cacerts/。
从 mitmweb 下载 Magisk 模块
如果你运行 mitmweb,你可以直接下载 Magisk 模块,而不必手工制作它:
停止你的 AVD,然后使用以下命令再次启动它:
-http-proxy 127.0.0.1:8080(或你运行 mitmweb 代理所使用的任何 IP 和端口组合)
然后,在 AVD 内,启动浏览器并导航到:
http://mitm.it/cert/magisk- 你将被提示下载
mitmproxy-magisk-module.zip,这就是你需要的 Magisk 模块。将该文件存储在某处(例如“Downloads”中)。 - 然后打开 Magisk,点击 Modules 并安装你的模块。
- 重启你的 AVD。
创建包含你的证书的 Magisk 模块
如果你不运行 mitmweb,你需要自己创建一个 Magisk 模块。有关 Magisk 模块的深入信息,请参见此处,但基本上可以归结为:
创建以下目录:
mitmproxycert (这将是你的模块根目录) mitmproxycert/com/google/android mitmproxycert/system/etc/security/cacerts将你在第 2 步中重命名后的证书放入
mitmproxycert/system/etc/security/cacerts,并对其执行:chmod 664- 将
https://github.com/topjohnwu/Magisk/blob/master/scripts/module_installer.sh的内容保存为本地文件update-binary,并放入mitmproxycert/com/google/android。 创建一个名为
updater-script的文件,其中仅包含字符串:#MAGISK并将其放入
mitmproxycert/com/google/android。创建一个名为
module.prop的文件,并将其放入mitmproxycert。该文件应包含类似以下内容:id=mitmproxycert name=MITM proxy certificate version=1 versionCode=1 author=mitmproxycert description=My shiny MITM proxy certificate to reveal all secrets and obtain world domination!使用类似以下命令将模块打包:
cd ./mitmproxycert ; zip -r ./../mitmproxycert.zip ./然后使用以下命令将其推送到你正在运行的 AVD:
adb push ./../mitmproxycert.zip /storage/emulated/0/Download/.- 然后转到你的 AVD,打开 Magisk,点击 Modules 并安装你的模块(你会在 Downloads 文件夹中找到它)。
- 重启你的 AVD。
API 级别 > 28 且使用 -writable-system 的说明
默认情况下,/system 分区以只读方式挂载。以下步骤描述了如何获得对 /system 分区的写入权限,以及如何复制第 2 章中创建的证书。
从 API 级别 29(Android 10)开始,似乎无法将“/”分区挂载为读写。Google 使用 OverlayFS 为此问题提供了解决方法。不幸的是,在撰写本文时(2021 年 4 月 11 日),此解决方法中的说明会导致你的模拟器陷入启动循环。Stackoverflow 上某个聪明人找到了一种仍然可以让 /system 目录可写的方法。
请记住:如果你想使用你的证书,你必须始终使用 -writable-system 选项启动模拟器。否则 Android 将加载一个“干净”的系统镜像。已在运行 API 级别 29 和 30 的模拟器上测试。
说明
列出你的 AVD:
emulator -list-avds(如果这返回空列表,请在 Android Studio AVD Manager 中创建一个新的 AVD)
启动所需的 AVD:
emulator -avd <avd_name_here> -writable-system(添加
-show-kernel标志以查看内核日志)以 root 身份重启 adb:
adb root禁用安全启动验证:
adb shell avbctl disable-verification重启设备:
adb reboot以 root 身份重启 adb:
adb root执行分区重新挂载为读写:
adb remount(如果 adb 告诉你需要重启,请再次重启
adb reboot并再次运行adb remount。)推送你在第 2 步中重命名后的证书:
adb push <path_to_certificate> /system/etc/security/cacerts设置证书权限:
adb shell chmod 644 /system/etc/security/cacerts/<name_of_pushed_certificate>重启设备:
adb reboot
API 级别 <= 28 且使用 -writable-system 的说明
已在运行 API 级别 26、27 和 28 的模拟器上测试。
请记住:如果你想使用你的证书,你必须始终使用 -writable-system 选项启动模拟器。否则 Android 将加载一个“干净”的系统镜像。说明
列出你的 AVD:
emulator -list-avds(如果这返回空列表,请在 Android Studio AVD Manager 中创建一个新的 AVD)
启动所需的 AVD:
emulator -avd <avd_name_here> -writable-system(添加
-show-kernel标志以查看内核日志)以 root 身份重启 adb:
adb root执行分区重新挂载为读写:
adb remount(如果 adb 告诉你需要重启,请再次重启
adb reboot并再次运行adb remount。)推送你在第 2 步中重命名后的证书:
adb push <path_to_certificate> /system/etc/security/cacerts设置证书权限:
adb shell chmod 644 /system/etc/security/cacerts/<name_of_pushed_certificate>重启设备:
adb reboot
测试你的证书是否从系统证书存储中加载
在你的 AVD 中,转到:
设置 → 安全 → 高级 → 加密与凭据 → 受信任的凭据
在列表中找到你的证书(默认名称为 mitmproxy)。

