
干安卓开发这些年我电脑上常驻的抓包工具就那几个。Charles、Fiddler、Wireshark都装过各有各的用处但要说“给安卓手机调试接口”这件事我最常开的还是Charles。它的图标是个瓶子圈里有人叫它“花瓶”也有人叫“青花瓷”名字挺文艺干活却特别硬核电脑上起一个代理手机把WiFi代理指过去所有HTTP和HTTPS请求就都被它截住、展开、看得清清楚楚。这篇文章我打算只讲一条主线安卓手机用Charles抓包从环境搭建到HTTPS证书设置再到那些一看就让人头大的报错比如unknown、SSLHandshake、证书下载失败统统过一遍。适合刚接触抓包的安卓开发者、刚入行的接口测试同学以及联调接口时被各种加密问题折磨的人。跟着走一遍你基本就能把这条链路打通后面再遇到问题也知道该往哪个方向排查。1. Charles到底在抓什么为什么安卓开发离不开它1.1 花瓶不是花瓶它是一个“中间人代理”很多新手第一次打开Charles看到一堆英文按钮就懵了。其实它的核心原理用一个生活类比就能讲清楚Charles相当于你小区门口的门卫。手机发出的每个网络请求原本是直接从你家窗户飞向服务器的。设置了代理之后请求先飞到门卫这里门卫拆开信封看一眼内容登记在案再把信重新封好寄出去。服务器回了信同样先到门卫手里门卫再检查一遍转交给你。于是门卫就拿到了你所有收发的信件内容这就是抓包。Charles干的就是这个门卫的活。它在你电脑上监听一个端口默认是8888手机或模拟器把代理指向这个端口流量就会经过它。它把每个请求记录下来、解析出来、展示在界面上最后转发给真正的服务器。不过这里有个关键区别HTTP请求是明文的门卫拆信就能看HTTPS请求是加密的门卫看到的是一堆乱码。这时候Charles就要使用“中间人”技术它会给客户端发一张自己签发的临时证书和客户端先建立一次加密连接然后它自己再以客户端的身份去和服务器建立另一次加密连接。中间这两段连接Charles都能解密看到明文。这就是为什么用Charles抓HTTPS必须安装它的根证书否则中间人角色无法建立。1.2 除了看请求它还能改请求、放断点、模拟弱网抓包只是基本功。Charles真正的价值在于“调试”它提供了一些接口联调时救命的功能。第一个是重放请求。你看到一个POST请求右键点击“Repeat”Charles会原封不动地把这个请求再发一次。调接口或者复现线上Bug的时候特别方便不用在App里一步步操作到那个页面。第二个是断点。你可以在请求发出前中断它在Charles里把参数改掉再放行也可以在响应返回前中断改掉返回的JSON再发给App。这样后端还没改好的接口客户端可以先拿假数据联调效率高很多。第三个是弱网模拟。在Proxy菜单下打开Throttle Settings可以设置带宽、延迟、丢包率。想测试App在2G/3G网络下超时或者断网重连的表现直接在这里给当前手机模拟一个弱网环境就能复现不需要真的找个信号差的地方。第四个是Map Local和Map Remote也就是把某个网络请求映射到本地文件或者另一台服务器。调试线上问题时我经常把线上接口的响应映射成本地写好的JSON文件客户端不用改代码就能走假数据流程非常实用。1.3 和Fiddler、Wireshark怎么分工很多人纠结要不要用Charles还是Fiddler或者干脆上Wireshark。我的经验是三个工具定位完全不同选对了场景才不别扭。工具定位最擅长的事Charles应用层HTTP/HTTPS调试代理看接口请求响应、改参数、重放、弱网模拟Fiddler同样是HTTP调试代理和Charles类似Windows生态里老牌脚本扩展多Wireshark网络层原始数据包抓取看TCP/UDP报文、分析协议栈、查底层网络问题如果你要调试的是App接口联调、参数校验、响应字段对不对用Charles或者Fiddler都行。如果你要分析一个TCP连接为什么老断、某个协议报文到底怎么交互的那得上Wireshark。Charles的应用层视角看不到这么深。所以这三者不是替代关系是互补关系。我电脑上三个都装了日常接口调试开Charles网络异常排查开WiresharkWindows机器上偶尔用Fiddler应急。2. 搭建抓包环境电脑、手机、模拟器一次连通2.1 电脑端安装和初始设置Charles的安装过程没什么坑。官网下载对应系统的安装包Windows直接双击安装Mac用户把app拖进Applications目录就行。装完打开界面很简洁左边是请求列表分成Structure和Sequence两个视图右边是请求详情区域上方是一排工具栏。打开之后第一件事我建议你先确认代理端口。点菜单栏的Proxy - Proxy Settings看HTTP Proxy标签页里是否勾选了“Enable transparent HTTP proxying”端口默认是8888。如果这个端口被别的程序占用了可以改成其他端口比如8899。改完之后手机端配置代理的时候要用新端口别两边不一致导致半天连不上。还有一个细节如果是你自己电脑上抓自己的浏览器流量Charles默认就能抓。但如果是给手机抓包需要确保Firewall端口允许8888通过尤其是Windows系统第一次启动如果弹防火墙提示记得勾选允许访问否则手机连过来会被拦在门外。2.2 让安卓手机连上Charles代理把手机和电脑放到同一个局域网里这一步是整个抓包环境的基础也是最容易出现低级错误的地方。先拿到电脑的局域网IP。Mac和Linux终端里输ifconfigWindows命令行里输ipconfig找到当前网卡的IPv4地址比如192.168.1.100。然后打开安卓手机的WiFi设置长按当前连接的WiFi选择“修改网络”把代理改成“手动”主机名填电脑的IP端口填8888保存。这时候随手打开手机浏览器访问一个普通的HTTP网站比如一些新闻站。第一次连接时Charles会弹出一个对话框问是否允许这台设备连接一定要点Allow。这一步经常被忽略如果你一直点Deny或者没注意到弹窗手机那边表现为能上网但Charles里一只包都看不到。点完Allow之后再回Charles看左侧列表应该能看到手机发起的请求按照域名分组出现。到这一步HTTP抓包链路就算通了接下来所有的问题基本都会集中在HTTPS上。2.3 真机和模拟器的差异模拟器场景有些不同单独提一下。雷电模拟器、夜神、MuMu这类模拟器默认运行在NAT网络模式下模拟器内部会通过一个虚拟网卡访问宿主机网络。在这种模式下你直接填电脑的局域网IP不一定能通因为虚拟网络和宿主机局域网之间的路由可能有问题。常见的做法有两种一种是在模拟器的代理设置里直接填宿主机IP但前提是网络配置里选的是“桥接模式”或者“主机模式”让模拟器和电脑处在同一个网络视图下。雷电模拟器的设置里网络相关选项可以调整不同版本入口不太一样搜一下就有。另一种是用模拟器内部的特殊宿主地址。很多模拟器里10.0.2.2这个地址指向宿主机。如果你在真机上填192.168.x.x不行可以试试在模拟器里填10.0.2.2端口还是8888。我以前用雷电模拟器踩过的一个坑是模拟器里能访问网络但Charles就是没流量。后来发现是模拟器的网络模式还是NAT代理填了局域网IP但不通改成10.0.2.2就好了。另外模拟器里如果要下载Charles证书浏览器访问chls.pro/ssl时字体可能很小点击操作不如真机方便这时候可以把证书文件下载到电脑上再直接拖进模拟器安装。模拟器抓包还有一个额外的好处性能比真机稳定适合长时间挂机跑自动化脚本时顺便把流量都录下来。2.4 代理连上了却没流量先查这三处每次有同事过来说“我代理设好了Charles一只包都没有”我的排查顺序基本固定这几年下来命中率很高。第一Charles到底点没点Allow。手机连过来时Charles会弹授权框如果没弹多半是手机和电脑不在同一网段或者Charles的Access Control设置里限制了IP。确认路径是Proxy - Access Control Settings看里面是否允许了你手机所在的IP段。第二手机系统和App是否真的走了系统代理。安卓的很多网络库特别是用OkHttp写的App默认会读取系统代理但有些App在代码里主动设置了Proxy.NO_PROXY意思是不走代理。这种情况下系统代理设了也没用流量会直连服务器Charles自然看不到。判断方法很简单换一个普通的浏览器App访问HTTP网站如果浏览器能抓到、目标App抓不到那就是App主动绕过了代理需要借助网络层转发工具做流量重定向或者换用抓取原始数据包的方式这属于进阶玩法了。第三端口和IP有没有填错。IP地址少了位数、端口写成了8080、手机连的其实是5G流量而不是WiFi这些都是我见过至少十几次的“灵异事件”。基础检查永远排在花式操作前面。3. HTTPS抓包证书体系与安卓系统安全机制3.1 为什么HTTPS抓出来全是unknown这是所有抓包新手都会遇到的第一堵墙。代理配好了HTTP网站能抓一到HTTPS就全部变成unknown点开请求响应是乱码或者直接显示连接失败。原因说起来很简单HTTPS的传输内容经过了TLS加密Charles这个“门卫”虽然拿到了密文但拆不开信封。要看明文Charles得先让客户端信任它然后它才能扮演中间人把加密链路“接一段、看一段、再转一段”。这个信任的建立方式就是让设备安装Charles的根证书。所以HTTPS抓包的完整链路其实有两步第一步是证书要装进手机并加入信任区第二步是Charles的SSL Proxying要开启并且覆盖目标域名和端口。这两个条件缺一个你看到的都是unknown。最近经常在群里看到有人问“我都把证书装上了怎么Windows本地抓包还是unknown”这个后面在问题清单里细聊但你要记住一个底层判断标准证书信任问题和SSL Proxying开关问题是两个独立变量排查时必须分别验证。3.2 别忘了开SSL Proxying开关证书装了、代理通了结果HTTPS还是抓不到最常见的第二个原因就是SSL Proxying没有开启。很多人看教程只学了装证书忽略了这个开关。Charles默认不会对所有HTTPS流量做中间人解密你得明确告诉它哪些域名、哪些端口需要解密。操作路径是Proxy - SSL Proxying Settings勾选Enable SSL Proxying然后在Location列表里添加规则。最省事的做法是添加一条Host填*、Port填443的规则意思是所有443端口的HTTPS流量都做解密。如果有些接口走非标准端口比如8443、8080也需要单独添加对应端口。我记得Charles界面上有一行英文提示“you may need to configure your browser or application to trust the Charles root certificate.”这句话的意思是你的浏览器或应用需要信任Charles的根证书否则握手阶段就会失败。很多人看到这行英文以为只是浏览器的问题其实在安卓抓包场景里它同样适用于手机上的App。证书没被信任SSL握手就过不了后面的解密无从谈起。3.3 安卓手机安装Charles根证书的正确姿势证书安装的完整流程我按现在的标准路径拆开讲顺序别乱。先在电脑上打开Charles点击菜单栏的Help - SSL Proxying - Install Charles Root Certificate on a Mobile Device or Remote Browser。这时候Charles会弹出一个提示框里面写了让手机浏览器访问的地址chls.pro/ssl。老版本可能提示的是charlesproxy.com/getssl逻辑一样都是Charles内置的一个证书下发地址。接着拿起手机确保手机上连的是已经设置了代理的WiFi打开浏览器访问chls.pro/ssl。正常情况下会开始下载一个证书文件文件名叫“getssl”或者“charles-proxy-ssl-proxying-certificate”后缀是pem或者crt。有些手机浏览器会直接弹出“安装证书”的界面有些则只是下载文件需要你手动去设置里安装。安卓系统装CA证书的路径一般在设置 - 安全 - 加密与凭据 - 安装证书 - CA证书。不同品牌的ROM菜单名称略有差异有的叫“证书管理”有的在“更多安全设置”里但关键词不离“安全”“凭据”“证书”这几个。点击安装选择刚下载的文件确认后系统会要求你输入锁屏密码验证身份之后证书就装上了。验证是否安装成功进入设置 - 安全 - 加密与凭据 - 信任的凭据 - 用户找到类似“Charles Proxy CA”的条目说明安装完成。一个小细节安卓系统版本越高对证书安装的权限控制越严格但至少在Android 14之前用户CA证书还是可以正常安装的只是路径藏得深一点。如果你找不到入口直接在系统设置的搜索框里搜“证书”基本都能定位到。3.4 Android 7.0之后的坑App默认不信任用户证书证书装好了HTTPS也开了SSL Proxying你在浏览器里能顺利抓包了但一打开目标App请求依然unknown、SSLHandshake失败、甚至直接connection reset。这个场景从Android 7.0开始就成了抓包界的第一大痛点。原因在这里从Android 7.0API 24开始系统默认只信任系统级别的CA证书不信任用户自己安装的CA证书。也就是说你装在“信任的凭据 - 用户”里的Charles证书只对浏览器和少数按照兼容老逻辑实现的App生效大部分App出于安全考虑网络请求都不会信任这个用户证书。怎么解决分情况。如果这个App是你自己开发的或者你有源码可以改那最简单的方案是在App里配置network_security_config.xml明确允许在调试场景下信任用户证书。文件放在res/xml目录下内容大概是network-security-config base-config cleartextTrafficPermittedtrue trust-anchors certificates srcsystem / certificates srcuser / /trust-anchors /base-config /network-security-config然后在AndroidManifest.xml的application标签里引用application android:networkSecurityConfigxml/network_security_config ...这样一来App就能信任你自己安装的Charles用户证书了。注意生产环境一般不建议长期这么干最好只在debug包或者测试环境开启避免降低安全性。如果不是自己开发的App那就麻烦一些。传统做法是root手机把Charles证书复制到系统证书目录让它变成系统CA。具体思路是通过openssl计算证书的subject_hash_old值把证书重命名成“值.0”的形式复制到/system/etc/security/cacerts/目录下修改权限为644重启手机。不同品牌ROM对/system分区的挂载方式不一样操作起来有的顺利有的折腾而且这种方式会改变设备的安全状态原则上只建议用来调试自己拥有或已获授权的设备。操作前记得备份数据。还有一批App更硬核直接在代码里做了SSL Pinning证书固定也就是只信任它自己内置的那张证书或指纹。这种App就算你把Charles证书装进系统目录握手阶段依然会失败抓包工具无能为力。要处理这种场景需要走更深入的安全测试思路比如hook代码绕过校验这属于另一个话题了我这里只提一个判断方向如果系统证书也装了、SSL Proxying也开了、协议也没问题但还是unknown那大概率就是Pinning在作怪。3.5 证书装好还失败的其他原因排除掉上面的大坑证书装好还失败还有一些隐蔽原因按我遇到的概率排个序。第一手机和电脑的时间不同步。TLS证书有有效期如果你手机时间比实际时间差了好几个小时Charles签发的临时证书在手机上会被判定为“不在有效期内”握手直接失败。我记得有一次折腾了快一个小时最后发现是手机时间快了五分钟。先校时再重试成本最低。第二目标请求走的不是443端口。有些App内部通信用了自定义端口比如8080、8443、9090你在SSL Proxying里只添加了443那这些请求不会被解密。Charles的规则是按host和port匹配的要抓哪个端口就加哪个端口最粗暴的做法是把端口范围填成1-65535但这样性能开销大不推荐长期开着。第三App使用WebSocket。wss协议本身也基于TLS同样需要证书信任和HTTPS的机制一样。如果你抓不到WebSocket帧先按HTTPS的证书流程排查。4. 高频报错与排查清单照着做就行4.1 一张表看懂常见故障把这几年群里问得最多的Charles安卓抓包问题整理成一个速查表遇到问题先对着查。现象可能原因解决思路手机能上网但Charles没数据代理没生效、Charles没点Allow、App主动不走代理检查代理IP/端口Charles授权弹窗点Allow换浏览器确认链路HTTPS请求显示unknownSSL Proxying没开、证书没装、Android 7用户证书不被App信任开启SSL Proxying并添加规则安装证书配置networkSecurityConfig或root后装系统证书手机浏览器无法下载证书证书下发域名被拦截、SSL Proxying未放行该域名临时关闭SSL Proxying再访问chls.pro/ssl下载完再打开模拟器抓不到包网络模式不通、代理地址填错填10.0.2.2或宿主机IP切换模拟器网络模式装了证书后Windows本机抓包还是unknown证书没装进系统根证书库、浏览器用的是独立证书库双击pem证书装到“受信任的根证书颁发机构”检查浏览器设置提示connection refused端口被占用、Charles没启动、代理端口写错确认8888监听状态重启Charles核对手机代理端口出现SSLHandshake certificate_unknown证书信任缺失、App做了SSL Pinning按第3章排查信任链路确认是否Pinning4.2 从上到下过一遍排查流程遇到问题不建议东点一下西点一下容易越搞越乱。我自己的排查顺序固定如下效率最高。第一步看代理。手机和电脑是否同一网段IP和端口是否和Charles一致。别信记忆打开Charles的Proxy Settings看一眼端口再去手机设置里看一眼两边对着确认。第二步看授权。Charles是否弹过Allow窗口或者Access Control Settings里是否允许当前设备接入。第三步验证纯HTTP。手机访问一个普通HTTP网站如果能抓到说明代理链路没问题问题出在HTTPS层面。如果HTTP也抓不到就回头查代理不用浪费时间看证书。第四步检查SSL Proxying。确认开关打开确认规则覆盖了目标域名和端口。第五步检查证书。安装位置对不对“信任的凭据 - 用户”里有没有Charles条目手机时间和电脑时间是否一致。第六步判断App的实现。是不是走了非标准端口是不是做了Pinning。到这个层面常规手段能做的都做完了剩下的就需要更专业的工具和思路。4.3 抓包数据怎么读手把手教你很多人抓到了包但看着一堆英文头大不知道怎么提取有效信息。我教个最基础的读包套路。Charles左侧有两个视图Structure按域名树状分组适合概览一个请求属于哪个接口Sequence按时间顺序排列适合看网络请求发生的先后时序排查“哪个请求先发出、哪个响应先回来”的问题。点中任意一个请求右侧会分几个标签页Overview、Contents、Headers、JSON、Raw等。我最常用的是Overview和JSON。Overview里能看到一个请求的完整概况包括URL、Method、Status、响应时间。JSON标签则是把响应体里的JSON格式化展示嵌套的字段一目了然。看一个请求我习惯先确认五件事请求的URL对不对、Method是不是预期的GET或POST、状态码是不是200/404/500、请求头里的Content-Type和Authorization是否正确、响应体里的核心字段是不是符合预期。这五件事覆盖了90%的接口联调问题。Filter输入框也特别好用。请求多的时候输入一个域名关键词或者接口路径列表立刻只显示匹配项省得在乱糟糟的请求海里捞针。4.4 四个让效率翻倍的小技巧最后分享几个我日常使用频率极高的Charles小技巧。第一个是Focus。在感兴趣的域名上右键选择Focus这个域名下的请求会以高亮颜色显示。配合Filter一用一屏能看清的请求特别干净。第二个是右键复制cURL Command。Charles把任何请求都能一键转成cURL命令拷贝到命令行里直接执行。这个在做问题复现、给后端同事传bug的时候太好用了把咖啡命令发过去对方直接能本地跑一遍。第三个是Breakpoints断点调试。工具栏上有个小人图标点一下开启断点模式然后在指定的请求上右键勾选Breakpoints。之后这个请求每次发出去之前Charles都会停下来等你编辑请求体点Execute才放行。响应也能同理修改。这个在联调阶段比反复改后端代码快得多。第四个是File - Save Session。抓完一整轮接口可以把整个会话保存成文件给同事或者留档。我比较喜欢在每次版本发版前把关键接口的会话单独存一份后续排查线上问题时有据可查。5. 几点踩坑之后的实在话如果只能给你一个建议我会说别一上来就折腾HTTPS。先用一个纯HTTP网站把链路彻底打通确认代理、Allow、端口都没问题了再去装证书、开SSL Proxying。很多人一上来就看HTTPS出了问题就懵其实HTTP层面的链路就是HTTPS的基础基础不稳后面全是白费。第二个建议是遇到unknown别慌90%的情况就俩原因SSL Proxying没开或者Android 7的用户证书不被App信任。先把这两个排除再考虑时间同步、非标端口这些冷门原因最后才轮到Pinning。别一开始就怀疑是App加密太强那样容易把自己绕进去。第三Charles试用版每次只能跑30分钟如果你只是临时调试试用到期重启一下也能续命但如果它是你的日常主力工具还是建议入手正版授权。网上那些注册名生成器看着省事但工具是吃饭的家伙工作流里埋这种雷没必要。我自己还有个习惯手机连代理测试完当场就把代理关掉。不关的话手机可能突然上不了网或者流量跑到一半卡住回头又以为电脑出问题了。Charles开着不影响但手机的代理状态一定要记得清理。把Charles用熟你会发现调试接口这件事能快一大截。从配代理、装证书、开SSL Proxying到看懂每个请求的来龙去脉这套链路值得每个安卓开发都走一遍。