ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Charles抓包实战:手机APP HTTPS解密与调试全攻略

Charles抓包实战:手机APP HTTPS解密与调试全攻略 做客户端开发或者接口联调的朋友应该都有过这种体验APP页面上数据渲染出来了但你想知道它到底是拿哪个接口的数据填的请求头带了什么参数后端返回的报文长什么样只能靠猜。或者测试环境报了一个线上问题你怀疑是接口返回异常但又没有后端日志权限只能干瞪眼。这种时候抓包工具就是救命稻草。Charles就是这样一款 HTTP/HTTPS 抓包代理工具我用了很多年从早期的 macOS 版一路用到现在。它的核心作用就一句话把手机APP发出的所有网络请求经过电脑中转转发到服务器中途把请求和响应完整记录下来并可以自由查看、修改、重放。不管是调试接口、分析协议、定位线上问题还是研究一个APP的通信逻辑Charles都是最顺手的工具之一。这篇文章就围绕“Charles如何对手机APP进行抓包”这个主题把我实际使用过程中的完整步骤、原理和踩坑经验都整理出来希望给你省点时间。1. 为什么移动开发离不开抓包Charles的核心价值1.1 抓包到底在抓什么先明确一个概念抓包抓的不是“手机屏幕上的内容”而是手机与服务器之间传输的HTTP/HTTPS报文。一次完整的HTTP请求通常包含几个核心要素URL接口地址包括域名、路径、查询参数Request Headers请求头比如 User-Agent、Cookie、Authorization、Content-TypeRequest Body请求体比如表单参数、JSON字符串Response Status状态码200、400、500等Response Headers响应头Response Body响应内容通常是JSON或HTMLCharles做的事情就是把自己变成一个“中间人代理”。手机把请求发给Charles所在的电脑Charles再转发给目标服务器服务器返回的数据先到CharlesCharles再转回给手机。在这个转发过程中Charles把经过的每一份请求和响应都做了完整备份显示在界面上给你看。用个生活化的类比你想知道快递从寄件人到收件人中间到底走了什么路径、箱子里面装了什么最直接的办法就是让快递在中转站停留一下由中转站工作人员拆开检查、记录、重新封装再发出去。Charles就是这个中转站。1.2 Charles相比其他抓包工具的优点抓包工具不止Charles一个常见的有Fiddler、Wireshark、Burp Suite它们各有侧重。简单说下我的感受Wireshark偏底层抓的是网络数据包能看到TCP三次握手、DNS解析这些链路层信息但对HTTP协议层不够友好数据需要自己去重组新手容易懵。Fiddler功能和Charles很像Windows上很流行但界面偏老在macOS上体验一般对HTTPS解密也需要装证书。Burp Suite安全测试利器功能强但偏重日常接口调试用它有点杀鸡用牛刀的感觉。Charles跨平台、界面简洁、对手机APP场景做了很多优化比如按域名整理接口、过滤器、断点调试、请求重放这些功能正好是移动开发调试的高频需求。所以我的结论是日常APP联调、接口排障首选Charles。它不需要手机root也不需要越狱iOS和Android通用对新手非常友好。2. 手机APP抓包前的准备安装、代理与连通性2.1 安装与环境准备Charles的安装没什么特殊门槛。官方渠道是官网下载对应系统版本macOS是dmg包Windows是exe安装包Linux也有对应的压缩包。安装完成后第一次启动默认会监听8888端口这是Charles的HTTP代理端口后续手机端的代理配置要和它保持一致。这里有个小细节Charles启动后你可以在菜单栏Proxy - Proxy Settings里看到和修改端口。如果8888被其他程序占用或者你因为网络环境原因需要换端口可以在这里修改。改完之后手机端配置代理时也要同步修改。除此之外还有一个容易忽略但很重要的动作确认电脑防火墙没有拦截来自局域网设备的入站连接。如果电脑开启了严格防火墙手机请求发过来会被拦掉表现就是手机连上代理后什么都打不开。Windows系统尤其容易遇到这个问题macOS相对好一些。2.2 手机与电脑建立代理链路这是整个抓包流程的基础链路不通后面全白搭。前提条件就一个手机和电脑连接到同一个局域网也就是同一台路由器的WiFi。具体操作分四步第一步查看电脑的局域网IP地址。macOS打开终端输入ifconfig | grep inet Windows打开命令提示符输入ipconfig找到无线网卡或者以太网卡的IPv4地址一般长这样192.168.x.x或10.x.x.x。记下这个IP。第二步设置手机WiFi代理。iOS路径设置 - 无线局域网 - 点击当前连接WiFi右侧的“i”图标 - 配置代理 - 手动。填入电脑IP和端口8888。Android路径不同厂商有所差异设置 - WLAN - 长按当前连接的WiFi - 修改网络 - 高级选项 - 代理 - 手动。填入电脑IP和端口8888。注意手机代理填的IP是电脑的局域网IP不是手机自己的IP。很多人这步填反导致链路不通。第三步在Charles上弹出连接确认框。当手机端配置好代理并开始产生网络请求时Charles会弹出一个提示框显示类似“Connection from 192.168.1.100”的提示询问是否允许该连接。这里要点击Allow否则Charles会拒绝手机发来的请求手机上所有联网操作都会失败。第四步点击Charles界面上的“Enable transparent proxying”启用透明代理按钮。这个按钮在较新版本的Charles里位于菜单栏Proxy下。它的作用是让Charles代理所有流向本机代理端口的HTTP请求。如果不开启即使手机代理配好了Charles也不一定会真正处理转发。2.3 验证链路是否打通配置完成后先不要急着上HTTPS先用HTTP验证链路。打开手机浏览器访问一个HTTP网站比如http://www.baidu.com。如果Charles界面的Structure或Sequence列表里出现了百度的请求条目说明代理链路已经打通可以继续下一步。如果什么都看不到先用下面的顺序排查手机和电脑是不是同一WiFi电脑IP填没填错端口是不是8888Charles有没有弹出Allow确认电脑防火墙有没有拦链路通了HTTP请求能看到了再进入下一关抓HTTPS。3. 抓HTTPS请求的关键一步SSL证书安装与信任3.1 为什么HTTPS请求显示为乱码或unknown现在绝大多数APP都强制使用HTTPS明文HTTP已经很少了。直接配置代理后你会看到Charles里出现了很多条目但点开一看全是乱码、或者直接显示unknown和Tunnel。原因很简单HTTPS是加密传输的Charles作为中间人必须让手机信任它自己生成的证书才能解密并查看请求内容。简单解释一下原理HTTPS的加密基于TLS/SSL证书。正常情况下手机和服务器直接建立加密连接中间人拿不到明文。Charles的做法是在手机和服务器之间插入自己手机向Charles发起连接时Charles用自己的证书伪装成目标服务器把这张证书发给手机同时Charles再向真正的服务器发起连接获取真实的响应。如果手机信任了Charles的证书那么手机和Charles之间的通信就是“加密但不保密”的因为密钥Charles也有Charles就能解密查看明文内容。这也是为什么很多安全敏感的APP会做SSL Pinning证书锁定在APP内部只信任特定证书拒绝Charles这种中间人证书从而防止抓包。这个后面会展开说。所以“证书安装与信任”是Charles抓HTTPS的核心步骤。装不好后面全白看。3.2 iOS手机证书安装与信任流程iOS的证书步骤相对明确但有一个关键点容易被漏掉我单独标出来。第一步下载证书。手机连接代理后用Safari浏览器访问http://chls.pro/ssl这个地址是Charles内置的证书下载入口。访问后手机会弹出一个“此网站正在尝试下载一个配置描述文件”的提示点击允许然后前往“设置”应用完成安装。第二步安装描述文件。在 设置 - 已下载描述文件 里找到Charles Proxy CA点击右上角“安装”输入锁屏密码确认。这一步完成后证书还只是“已安装”状态但iOS默认不会信任用户安装的CA证书。第三步最容易被忽略的一步开启证书完全信任。在 设置 - 通用 - 关于本机 - 证书信任设置 里找到Charles Proxy Custom CA把开关打开选择“完全信任”。亲测下来很多人在第二步安装完就以为完事了结果Charles里还是显示unknown折腾半天才发现是这个开关没开。iOS的“安装证书”和“信任证书”是两码事必须两步都做。3.3 Android手机证书安装的差异与新版本坑Android端证书安装比iOS麻烦一些而且从Android 7.0API 24开始有一个非常知名的坑这里详细说。Android 7.0以下设置 - 安全 - 更多安全设置 - 从存储设备安装证书 - CA证书。选择从手机存储中找到chls.pro/ssl下载的证书文件通常叫charles-proxy-ssl-proxying-certificate.pem安装完成即可。Android 7.0及以上Google从Android 7.0开始默认不信任用户安装的CA证书也就是你装了Charles证书但绝大多数APP根本不会使用这个证书去校验网络请求结果就是抓到的HTTPS请求依旧是unknown。这个限制不是Charles能解决的它属于Android系统API层面的默认行为。常见的解决方案有这么几种改APP代码做适配在APP的network_security_config.xml中配置信任用户证书或者在AndroidManifest里指定android:networkSecurityConfig。这是开发这个APP的人才能做的适合你手上有源码的情况。把证书移入系统证书目录需要手机root然后将证书文件复制到/system/etc/security/cacerts/目录并确保权限正确。这个方法一劳永逸但要求root权限不是所有设备都方便。用低版本系统模拟器/真机Android 6.0或更低版本没有默认限制测试兼容旧系统的APP时可以考虑。使用支持安装证书的模拟器比如某些定制ROM的模拟器已经把用户证书信任到系统层抓包会方便很多。实操心得如果你在Android 10、11等新版本真机上抓包遇到APP的HTTPS请求全是unknown先确认不是证书问题再考虑是否用了系统代理检测。很多APP做了代理检测发现你开了代理就直接不走网络或者上报异常这时候需要配合其他工具处理Charles单独是搞不定的。4. 从海量请求里快速定位目标过滤、改名与断点4.1 用Filter栏按域名过滤手机APP一运行后台会发起一堆请求统计上报、日志上报、广告请求、图片资源……全都混在一起直接看Structure列表会非常乱。Charles右上角有一个Filter输入框这个功能我用得最频繁。它的作用很简单只显示URL匹配过滤条件的请求。比如你只关心login相关接口就输入login列表里立刻过滤出所有URL中包含“login”的请求。你想看某个域名下的所有接口输入api.example.com即可。支持*通配符比如*.example.com。需要注意Filter是即时过滤不影响Charles已经记录的数据。如果你过滤掉一批请求它们还在Session列表里只是不显示了。4.2 Focus与高亮只显示关心的请求Filter适合临时过滤但如果要长期关注某个域名的请求每次手动输入关键词太烦了。Charles提供了Focus聚焦功能在请求列表的某个域名上右键选择Focus之后这个域名的请求会默认高亮显示而且可以在Structure视图下单独展开看。Proxy - Focus Settings里可以看到当前Focus的域名列表可以手动增删。配合Filter和Sequence视图几乎可以做到只看目标接口其他请求一律忽略非常省心。4.3 Breakpoints与Map Local调试和后端未完成时的救命稻草Charles不只是“看”还能“改”。这个能力在联调阶段直接提升幸福感。Breakpoints断点在某个请求上右键选择Enable Breakpoints之后这个请求每次通过网络时都会中断在Charles界面你可以手动修改请求头、请求体或响应体再点击执行继续。这意味着你不需要改APP代码就能模拟各种后端返回结果改一个JSON字段的值、把错误码改成成功、把返回数据置空等。实际场景举例后端某个字段的值还没定你想知道前端对不同取值是怎么处理的。用断点拦截响应手动修改后放行前端立刻反应成不同的UI状态联调效率显著提升。Map Local映射到本地右键请求 -Map Local可以把某个接口的响应映射到本地的一份JSON文件。之后Charles拦截到对这个接口的请求时不转发到服务器直接用本地文件作为响应返回。后端接口还没完成、或者线上环境不能随便改数据时这个功能非常有用。用法很简单点击Tools - Map Local勾选Enable添加一条映射规则填写协议、主机、端口、路径然后在“Local path”里选择本地文件即可。实操心得Map Local调试时本地文件里的Content-Type要和真实接口保持一致尤其是接口返回的Content-Type是application/json时本地文件也要是这个否则部分APP解析会报错。5. 抓包现场一次完整的APP接口调试复盘5.1 场景介绍与目标空谈步骤比较抽象我拿一个实际的调试过程做例子。假设有一款APP的登录接口一直报错后端说“我这边返回是正常的”前端怀疑“是不是请求参数格式不对”。我们通过Charles来定位问题。复现环境手机Android真机电脑macOS目标抓取APP内登录接口的完整请求和响应5.2 操作全过程记录第一步打开Charles确认端口是8888开启透明代理。第二步手机连上同一WiFi设置代理为电脑IP 8888Charles弹出来自手机的连接确认框点击Allow。第三步在Charles顶部Filter栏输入login过滤出登录相关请求。第四步在手机上打开APP输入测试账号密码点击登录按钮。第五步回到Charles看到列表里出现POST /api/v1/login的请求条目。点击进去切换到“Contents”标签页查看内容。这里我看到了如下关键信息请求URLhttps://api.example.com/api/v1/login请求方式POSTContent-Typeapplication/json; charsetutf-8请求体{username:test,password:123456}响应状态码400响应体{code:400,message:invalid request format}5.3 数据分析和问题定位看到invalid request format问题基本浮出水面。后端猜测信息服务端可能期望的是表单格式application/x-www-form-urlencoded但前端发送的是JSON格式。为了验证这个猜测我在Charles里对这个请求右键选择Repeat重放或者用断点修改请求头把Content-Type改成application/x-www-form-urlencoded并把请求体改成usernametestpassword123456再重新发送。结果请求成功返回200登录成功。问题定位完成确实是前后端约定的请求格式不一致Charles给出了最直接的证据。这个案例说明Charles在联调中的价值不只是“看数据”还能通过重复请求、修改参数做快速验证。不用改代码、不用发版本、不用等后端操作一个人就能完成排查闭环。6. 常见问题与排错经验速查表这一部分把日常遇到概率最高的几个问题整理成一个速查表方便你直接对号入座。现象可能原因解决办法手机配了代理后完全无法上网代理IP或端口填写错误Charles未开启透明代理Charles未点击Allow核对IP和端口确认Charles开启透明代理重新触发连接并点击AllowCharles列表里看不到任何手机请求手机和电脑不在同一局域网电脑防火墙拦住入站连接确认同一WiFi关闭或配置防火墙放行8888端口只能看到Tunnel或unknownHTTPS未解密证书未安装或未信任安装证书iOS开启证书完全信任Android确认系统版本是否信任用户证书证书安装成功但依然看不到HTTPS明文Android 7.0默认不信任用户证书APP做了SSL Pinning改用低版本系统修改APP配置信任用户证书root后安装到系统证书目录某个APP能抓到HTTP但抓不到HTTPSAPP内部做了证书校验或代理校验检查是否存在SSL Pinning或代理检测逻辑需要配合绕过方案Charles里所有请求都是乱码HTTP压缩Gzip/Brotli且未自动解压检查请求/响应头是否有Content-EncodingCharles一般会自动处理乱码常见于非标准协议或Dubbo等二进制协议6.1 为什么抓不到任何请求这是新手最常问的问题。链路配置没问题的话大概率是代理设置没有生效。Android上有些应用不走系统代理尤其是使用OkHttp且未配置代理的APP它们会忽略系统WiFi代理设置。遇到这种情况可以用Charles的透明代理配合iptables进行强制流量转发但这部分操作比较复杂普通调试场景很少用到。6.2 为什么全是unknown或TunnelTunnel这个关键字很能说明问题Charles接收到的是HTTPS加密流量但客户端手机APP没有信任Charles的证书所以Charles无法解密只能显示这是一个Tunnel连接任务是原样透传。解决办法回到第3章重新检查证书安装和信任流程。6.3 为什么证书装好了还是看不到明文除了Android高版本的问题iOS还有一个常见坑证书安装了但“证书信任设置”没有打开完全信任。另一个隐蔽问题证书安装成功后会过期Charles版本升级后也可能更换证书。遇到这种情况重新下载安装新证书并再次确认信任开关是打开的。6.4 为什么有些APP一抓包就闪退或提示无网络这不是Charles坏了而是APP做了反抓包检测。常见的手段包括检测到系统代理就拒绝服务、在代码里校验证书指纹SSL Pinning、甚至检测到开发调试特征就主动退出。面对这种情况常规的Charles配置已经不够了需要配合Frida、xposed等动态插桩工具来绕过这属于应用安全测试的范畴就不在这篇文章里展开了。7. 总结之外的一些实践经验文章写到这里核心内容基本讲完了。最后分享一个我自己的习惯每次抓包前我都会在Charles里先清理一次会话记录快捷键CmdZ是清空当前列表或者用菜单 Session - Clear。这样做的目的是减少杂音干扰让手机APP启动后的第一批请求全部集中在干净的Session里定位问题时会快很多。另外抓包完成后记得关闭手机端的代理设置恢复正常的WiFi连接。很多次我看到群里有人问“为什么我手机突然不能上网了”结果都是因为忘了关代理WiFi图标下面挂着一串代理配置却毫不知情。这点细节处理好了能省掉不少尴尬。Charles是一个简单强大、但上限极高的工具。这篇文章只覆盖了最常用的抓包、HTTPS解密、过滤、断点和重放功能。它还有像是请求比较、导出数据、多客户端支持等高级功能等你自己上手之后自然会慢慢探索到。希望这篇文章能帮你少踩几个坑顺利把第一个APP的请求抓出来。
返回列表