1. 项目概述为什么Android 7.0的HTTPS抓包是个“坎”如果你是一名移动端开发、测试或者安全研究员想在Android手机上抓取HTTPS流量大概率听说过Charles的大名。这确实是个神器在Android 6.0及之前的系统上配置起来相对“无脑”手机装个证书设置好代理流量就乖乖地流过来了。但自从Android 7.0API Level 24开始事情就变得复杂了。很多朋友兴冲冲地按照老教程操作结果Charles里看到的HTTPS请求要么是一片unknown要么就是直接报SSL handshake failure折腾半天一头雾水。这个“坎”的核心在于Android系统从7.0开始引入了一项更严格的安全策略网络安全配置Network Security Configuration。简单来说系统不再默认信任用户安装的CA证书就是你从Charles导出的那个证书除非你明确告诉它“这个App可以信任用户证书”。这就好比你家小区Android系统升级了门禁以前访客用户证书登记一下就能进现在必须业主App亲自到门口来接或者提前在物业App的配置那里备案才行。这个变化直接导致了沿用多年的“装证书-设代理”一键抓包法在大部分App上失效。所以这篇指南要解决的就是如何跨过Android 7.0这个安全门槛让Charles重新成为你洞察App网络行为的“眼睛”。我们会从原理讲起覆盖从基础配置到针对不同App的进阶破解方法最后还会分享一些实战中积累的排查技巧和独家心得。无论你是想调试自家App的API调用还是分析第三方App的数据交互这篇内容都能给你一套清晰的、可落地的解决方案。2. 核心原理与前置准备理解证书信任链在动手之前我们必须先搞清楚HTTPS抓包的本质。Charles这类工具之所以能解密HTTPS流量扮演的是一个“中间人”Man-in-the-Middle, MITM的角色。正常流程是“客户端 – 服务器”而抓包时变成了“客户端 – Charles – 服务器”。Charles在中间分别与客户端和服务器建立TLS连接并对流量进行解密、查看、再加密转发。这个过程能成功的关键在于证书信任。当客户端你的手机连接到Charles时Charles会动态生成一个针对目标域名的证书发给客户端。如果客户端信任签发这个证书的根证书颁发机构CA那么TLS握手就能成功Charles就能看到明文。因此我们必须让手机系统信任Charles的根证书。在Android 7.0之前把Charles的CA证书安装到“系统信任的凭据”里就足够了因为所有App都信任系统证书库。但7.0之后App默认只信任系统预装的CA证书不信任用户后来添加的。这就是我们所有麻烦的根源。基于这个原理我们的准备工作分为三块Charles端、手机端和网络环境。2.1 Charles端基础代理与SSL代理设置首先确保你的Charles已经正确安装并运行。我这里以macOS版为例Windows/Linux版操作逻辑一致。启动Charles并设置代理监听打开Charles进入菜单Proxy - Proxy Settings...。在Proxies标签页下确保Enable transparent HTTP proxying被勾选。记住默认的HTTP Proxy端口通常是8888。你也可以改成其他未被占用的端口。勾选底部的Support HTTP/2和Enable SSL Proxying这个我们后面细配。配置SSL代理关键步骤这是告诉Charles需要对哪些域名的HTTPS流量进行解密。进入菜单Proxy - SSL Proxying Settings...。在SSL Proxying标签页勾选Enable SSL Proxying。点击Add按钮在Host字段填入*Port字段填入443。这是一个通配符配置意味着对所有443端口的HTTPS流量都尝试进行MITM解密。在实际调试中你也可以针对特定域名如*.example.com进行配置以减少无关干扰。注意通配符*虽然方便但在访问一些证书固定Certificate Pinning特别严格的网站如银行、大型社交App时可能会失败这时就需要更精细的配置或绕过方案。获取Charles的根证书这是待会要安装到手机上的“钥匙”。在Charles中进入菜单Help - SSL Proxying - Save Charles Root Certificate...。选择保存为.pem或.crt格式。我通常保存为charles-ssl-proxying-certificate.pem方便识别。2.2 手机端连接同一网络与基础代理配置确保手机与电脑在同一局域网这是最基本的前提。手机和运行Charles的电脑必须连接到同一个Wi-Fi网络。查询电脑的局域网IP在Charles中你可以通过Help - Local IP Address查看。或者在电脑终端输入ifconfig(macOS/Linux) 或ipconfig(Windows) 来查找。在手机上配置代理进入手机的Wi-Fi设置长按当前连接的Wi-Fi网络选择“修改网络”或“高级选项”。将代理设置为“手动”。主机名填入上一步查到的电脑IP地址。端口填入Charles中设置的代理端口默认8888。保存。首次信任Charles完成代理设置后用手机浏览器打开任意HTTP网站如http://neverssl.com此时Charles会弹出连接确认框询问是否允许该设备连接。点击Allow。至此HTTP流量应该已经能在Charles中看到了。2.3 网络环境与工具准备关闭手机VPN和流量确保手机没有开启任何VPN软件并且暂时关闭移动数据只使用Wi-Fi避免流量走其他通道。准备文件传输工具你需要一个方便的方式将Charles根证书文件传输到手机。可以用数据线连接电脑也可以用局域网文件共享工具如LocalSend、聊天软件或网盘。准备ADB工具可选但强烈推荐Android Debug Bridge (ADB) 是后续很多高级操作特别是系统级证书安装的必备工具。去Android开发者官网下载并配置好Platform Tools确保在终端可以执行adb命令。同时需要在手机的“开发者选项”中开启“USB调试”。3. 核心攻坚针对不同场景的证书安装策略准备工作就绪现在进入最核心、也最容易出问题的环节——让Android系统或目标App信任Charles的证书。根据你的目标调试自己开发的App还是分析第三方App和手机条件是否已Root策略完全不同。3.1 场景一调试自己开发或可修改的App最推荐这是最理想的情况你有App的源代码或构建能力。方法是通过修改App的网络安全配置让它显式地信任用户证书。将Charles证书放入App资源将之前保存的charles-ssl-proxying-certificate.pem文件重命名为charles.crtAndroid通常识别.crt或.cer后缀。把这个文件放到你Android项目的res/raw/目录下。如果没有raw目录就创建一个。创建或修改网络安全配置文件在res/xml/目录下创建或修改network_security_config.xml文件。写入以下配置内容?xml version1.0 encodingutf-8? network-security-config base-config cleartextTrafficPermittedtrue trust-anchors !-- 信任系统预装证书 -- certificates srcsystem/ !-- 信任我们放置在raw目录下的用户证书 -- certificates srcraw/charles / /trust-anchors /base-config /network-security-config这个配置做了两件事一是允许明文HTTP流量cleartextTrafficPermittedtrue便于抓非HTTPS流量二是将系统证书和我们自定义的Charles证书都加入信任锚点。在AndroidManifest.xml中引用该配置打开AndroidManifest.xml文件在application标签内添加android:networkSecurityConfig属性。application ... android:networkSecurityConfigxml/network_security_config ... ... /application重新编译并安装App使用Android Studio重新构建并安装Debug版本的App到手机。现在这个App发出的HTTPS请求应该就能被Charles正常解密了。实操心得这种方法一劳永逸且只对你自己的App生效不影响手机其他App的安全性是最安全、最规范的开发调试方式。建议将network_security_config.xml文件配置为仅debug构建变体使用在release版本中移除避免安全隐患。3.2 场景二针对未Root的Android 7.0-8.0设备对于没有源码的第三方App且手机系统版本在Android 7.0到8.0之间我们还可以尝试利用一个“后门”将用户证书安装到系统证书库但这需要ADB和一定的命令行操作。注意Android 9.0 (Pie) 及更高版本彻底关闭了这个后门。将证书转换为Android系统识别的格式系统证书要求特定的文件名和格式。打开终端进入存放Charles证书.pem文件的目录。执行以下命令# 计算证书的哈希值并以此命名 openssl x509 -inform PEM -subject_hash_old -in charles-ssl-proxying-certificate.pem | head -1命令会输出一个类似c8750f0d的哈希值。将这个哈希值加上.0作为后缀就是系统证书的文件名例如c8750f0d.0。生成系统证书文件# 将PEM证书转换为DER格式并用哈希值命名 openssl x509 -inform PEM -in charles-ssl-proxying-certificate.pem -outform DER -out c8750f0d.0将证书文件推送到系统证书目录这需要ADB shell并具有root权限。对于未Root但系统版本9的设备我们可以尝试挂载系统分区为可写。手机通过USB连接电脑并开启USB调试。在终端执行adb root # 尝试获取root权限非Root设备可能失败 adb remount # 尝试重新挂载系统分区为可读写此命令也需要特定条件如果adb remount成功继续执行adb push c8750f0d.0 /system/etc/security/cacerts/如果adb remount失败在大多数未Root的零售设备上都会失败则此路不通。对于这部分设备场景二的方法基本失效需要转向场景三或场景四。修改证书权限并重启adb shell # 进入证书目录 cd /system/etc/security/cacerts/ # 修改证书文件权限为644 (rw-r--r--) chmod 644 c8750f0d.0 # 退出shell并重启手机 exit adb reboot手机重启后Charles证书理论上就被系统全局信任了。你可以去手机的“设置 - 安全 - 加密与凭据 - 信任的凭据 - 系统”里查看应该能找到以“Charles Proxy…”或你计算出的哈希值命名的证书。踩过的坑adb remount成功与否高度依赖设备厂商和系统版本。在Google Pixel的官方镜像或一些开发者友好的设备上可能可行但在华为、小米、OPPO、vivo等厂商的零售机上几乎百分之百会失败因为系统分区被严格锁定。不要在这个方法上耗费太多时间。3.3 场景三针对未Root的Android 8.0设备使用平行空间/虚拟机既然无法动真机的系统一个巧妙的思路是“创造一个可以控制的环境”。这就是使用平行空间Parallel Space、VirtualXposed、VMOS等应用虚拟化/虚拟机工具的原因。这些工具在App内部创建了一个虚拟的Android环境我们可以在这个虚拟环境里安装并信任Charles证书。在虚拟环境中安装Charles证书在真机上安装好平行空间等工具。在平行空间内部安装你需要抓包的目标App例如微信。同样在平行空间内部通过浏览器访问chls.pro/sslCharles提供的证书下载快捷地址下载证书并按照提示安装到“虚拟环境”的“用户凭据”中。关键点来了平行空间这类App其内部的虚拟系统通常没有遵循Android 7.0的严格限制或者其自身的网络配置允许信任用户证书。因此安装在虚拟环境“用户凭据”里的证书对运行在同一个虚拟环境里的App是有效的。配置虚拟环境的网络代理你需要在平行空间等工具的设置里找到网络或代理配置选项将代理指向你电脑的CharlesIP和端口8888。这个设置位置因工具而异需要仔细查找。启动抓包在平行空间里启动目标App进行操作Charles就能抓到解密后的HTTPS流量了。注意事项这种方法性能有损耗且并非所有App都能在虚拟环境中完美运行尤其是强依赖特定硬件或安全环境的App如银行类。但对于微信、电商、资讯等大多数App成功率很高。这是目前针对高版本非Root安卓机抓包第三方App最主流、最有效的方法。3.4 场景四终极方案——Root你的设备如果你有一台专门用于测试、研究的备用机获取Root权限是最彻底、最强大的解决方案。Root后你可以直接修改系统分区将证书放入/system/etc/security/cacerts/一劳永逸。Root设备具体Root方法因手机品牌和型号差异巨大通常需要解锁Bootloader、刷入自定义Recovery如TWRP、再刷入Magisk。这个过程有变砖风险请务必提前查找对应机型的详细教程并备份数据。安装Magisk模块推荐Root后更优雅的方式是使用Magisk模块。有一个名为“Move Certificates”的模块或者你可以自己创建一个模块其作用就是将用户证书目录 (/data/misc/user/0/cacerts-added/) 下的证书在系统启动时自动链接到系统证书目录。这样你只需要像在Android 6.0上一样在设置里安装Charles证书到“用户凭据”重启后它就会自动被系统全局信任。手动推送证书如果没有Magisk模块也可以在Root后通过ADB直接执行场景二中因权限失败的那些命令adb root # 这次应该能成功获取root shell adb remount # 重新挂载系统为可读写 adb push c8750f0d.0 /system/etc/security/cacerts/ adb shell chmod 644 /system/etc/security/cacerts/c8750f0d.0 adb rebootRoot后整个世界都通畅了。不仅抓包很多其他高级调试和分析工作也变得可能。4. 实战演练以抓取微信小程序HTTPS流量为例理论讲完了我们用一个实战案例串起整个流程。假设我们要分析某个微信小程序的网络请求。目标在未Root的Android 10手机上抓取微信内小程序的HTTPS流量。选用方案场景三——使用平行空间这里以“平行空间”App为例其他类似工具操作逻辑相通。步骤详解Charles端准备确保Charles已开启SSL Proxying设置中已启用并添加了*:443。记下电脑的IP地址如192.168.1.100和代理端口8888。手机基础配置手机连接与电脑相同的Wi-Fi。在手机系统Wi-Fi设置中暂时不配置全局代理。因为我们要在平行空间内部配置代理。平行空间内操作安装并打开“平行空间”。在平行空间内点击“添加应用”找到并添加“微信”。平行空间会克隆一个微信的副本。在平行空间内还需要添加一个浏览器比如系统自带的浏览器或你安装的Chrome。通过这个内部浏览器访问chls.pro/ssl下载Charles证书。下载完成后系统会提示安装证书。给证书起个名字如“Charles Proxy”并选择安装到“VPN和应用”或“用户凭据”类别。务必确保在平行空间的环境内完成此操作。在平行空间的设置菜单中通常需要点击平行空间主界面的某个设置图标或菜单键寻找“网络设置”或“代理设置”。将代理模式改为手动填入主机名192.168.1.100和端口8888。开始抓包回到Charles确保其正在捕获流量。在平行空间内启动刚刚添加的“微信”。登录微信打开你想要分析的小程序。此时Charles的界面中应该开始出现来自你手机IP的流量。找到主机名明显是小程序域名的请求通常是wxapp.com,tencent.com, 或小程序自己的业务域名如果SSL代理配置正确这些HTTPS请求的内容应该是可读的明文而不是unknown或乱码。验证与排查如果看到的是unknown首先检查Charles的SSL Proxying是否对该域名生效。可以在该请求上右键选择 “Enable SSL Proxying”Charles会自动将其添加到SSL代理列表。如果出现证书错误检查平行空间内的证书是否确实安装成功。可以尝试在平行空间内用浏览器访问一个普通的HTTPS网站如https://example.com看Charles能否解密。如果不能说明平行空间内的代理或证书配置有问题。独家技巧微信自身和一些大型App会使用证书固定Certificate Pinning即使系统信任了Charles的根证书App自身也会校验服务器证书是否来自特定的、预期的CA。对于这种情况常规的MITM方法会失败。此时就需要更高级的工具如基于Frida的脚本例如objection的android sslpinning disable命令来动态绕过证书固定。但这需要手机具备Root权限或运行Frida Server进入了移动安全逆向的领域复杂度更高。5. 高级技巧与深度问题排查即使按照上述步骤操作你可能还是会遇到各种“诡异”的问题。这里分享一些进阶排查思路和技巧。5.1 抓包失败常见原因与解决方案速查表现象可能原因排查步骤与解决方案Charles无任何流量1. 手机代理未正确设置。2. 电脑防火墙阻止了Charles端口。3. 手机和电脑不在同一网络。1. 确认手机Wi-Fi代理的IP和端口无误。2. 暂时关闭电脑防火墙或添加规则允许Charles入站。3. 互相ping一下IP确认网络连通性。只有HTTP流量HTTPS全是unknown1. 手机未安装/未信任Charles根证书。2. Charles未启用SSL Proxying或未包含目标域名。1. 确认证书已安装到正确位置用户凭据/系统证书。对于Android 7.0第三方App确认使用了场景三或场景四的方案。2. 检查Charles的Proxy - SSL Proxying Settings确保已启用并添加了*:443或具体域名。HTTPS请求显示SSL handshake failure1. 证书不受信任根本原因。2. 目标服务器使用了不常见的TLS版本或加密套件。3. 客户端使用了证书固定。1. 重点检查证书信任链问题参考本文场景一至四。2. 在Charles的Proxy - SSL Proxying Settings - Advanced中尝试勾选更多TLS版本如TLS 1.0, 1.1, 1.2, 1.3。3. 对于证书固定需要借助Frida等动态插桩工具绕过或尝试在低版本Android上运行该App。部分App流量抓不到1. App使用了HTTP/3 (QUIC)。2. App使用了自定义Socket或非标准端口。3. App检测并禁用了代理如使用Proxy.NO_PROXY。1. Charles默认不支持HTTP/3。可尝试在Charles或系统设置中禁用QUIC。2. 这类流量Charles可能无法自动解码需要结合其他工具如Wireshark进行原始流量分析。3. 需要使用VPN模式抓包如搭配Packet Capture App或使用透明代理网关。平行空间内App无法联网平行空间内的代理设置错误或该虚拟环境本身网络异常。1. 检查平行空间内的代理配置IP和端口。2. 尝试在平行空间内用浏览器访问http://www.baidu.com看是否通。3. 重启平行空间或更换其他虚拟机工具如VMOS尝试。5.2 使用ADB辅助安装用户证书Android 9部分机型有效对于Android 9及以上系统虽然无法直接安装到系统证书但有一个通过ADB安装用户证书的命令有时可以绕过图形界面的限制尤其适合一些定制系统证书安装界面有问题的手机。# 将证书文件推送到手机存储 adb push charles-ssl-proxying-certificate.pem /sdcard/Download/ # 通过ADB shell命令调用系统安装证书的Intent adb shell am start -a android.settings.MANAGE_APPLICATIONS_SETTINGS # 注意上述命令只是打开设置页面安装仍需手动。 # 更直接的方式是在手机已开启“开发者选项”-“USB调试安全设置”或“USB安装”时尝试 adb shell settings put global verifier_verify_adb_installs 0 # 然后尝试通过ADB安装一个包含证书安装逻辑的辅助App需自行开发或寻找但这已超出常规范围。实际上对于高版本Android最通用的方法还是场景三虚拟机。ADB安装用户证书的命令 (adb shell pm install-cert) 并不存在最终仍需用户手动在设置界面操作。5.3 应对证书固定SSL Pinning这是抓包路上的终极Boss。当App硬编码了只信任特定证书时即使系统信任了Charles的证书也没用。识别Charles中该域名的请求直接失败错误信息可能包含“Certificate pinning failure”或“SSL handshake failed”。解决方案低版本Android尝试在Android 7.0以下的设备或模拟器上运行该App旧版本可能未实施证书固定。使用Frida等动态插桩工具这需要一定的逆向工程知识。基本原理是向目标App进程注入脚本Hook其证书验证的相关函数如OkHttp的CertificatePinner或底层的X509TrustManager使其验证逻辑失效。可以使用现成的脚本如# 假设已安装frida-tools且手机已运行frida-server frida -U -f com.target.app --no-pause -l ssl-pinning-bypass.js修改App并重打包仅限自有或可修改的App在代码中移除证书固定的逻辑或者像场景一那样配置network_security_config.xml时添加domain-config并设置cleartextTrafficPermittedtrue和pin-set为空或包含你的Charles证书指纹极不推荐仅用于测试。5.4 Charles的其他实用配置过滤请求在Charles界面左下方的Filter栏输入主机名关键词可以快速聚焦目标流量避免被海量请求淹没。断点与修改在请求上右键选择Breakpoints可以设置请求断点。当请求发出时Charles会暂停允许你查看并修改请求参数后再转发当响应返回时也可以修改响应内容后再返回给客户端。这对调试接口异常或模拟特定场景极其有用。映射本地文件/远程地址Tools - Map Local可以将特定请求映射到本地的一个文件用于模拟接口返回数据。Tools - Map Remote可以将请求重定向到另一个远程地址。流量重放与压力测试选中一组请求右键Repeat或Repeat Advanced可以多次重复发送用于测试接口的并发性能或稳定性。6. 总结与个人体会Android HTTPS抓包的配置从Android 7.0开始从一个简单的操作变成了一个需要根据目标、设备和系统版本“因地制宜”的技术活。核心矛盾始终围绕着“如何让目标App信任Charles的根证书”展开。对于开发者优先采用修改自己App网络安全配置场景一的方式这是最规范、最安全的做法。对于测试或安全分析人员面对第三方App平行空间等虚拟机方案场景三是目前应对高版本非Root设备最实用的选择它巧妙地避开了系统级的限制。如果你拥有设备的完全控制权Root那么世界就是你的游乐场可以尝试任何深度定制。在整个过程中耐心和细致的排查至关重要。大部分问题都出在证书信任、代理设置和网络环境这三个环节。养成“先确认HTTP流量能否抓到再解决HTTPS问题”的排查习惯能帮你快速定位问题所在。最后对于越来越普遍的证书固定需要意识到这已经进入了移动应用安全的攻防领域需要学习更多逆向工程和动态分析的知识来应对。我个人在无数次抓包调试中最大的体会是工具是死的思路是活的。Charles只是一个抓手真正重要的是理解HTTPS协议、Android安全机制和网络调试的基本原理。当你明白了Charles为什么能解密流量Android又为什么不让它解密时所有看似复杂的配置步骤就都成了顺理成章的操作。遇到问题别慌按照信任链系统-App-证书和网络路径手机-代理-服务器一层层查下去总能找到突破口。