最近在折腾接口调试的时候,发现身边还是有很多人一碰到HTTPS就抓瞎——明明开启了抓包工具,看到的却是一堆加密乱码;或者好不容易电脑上能抓了,一转到雷电模拟器里又什么都看不到。其实这套东西并不复杂,核心就是搞明白HTTPS证书信任和代理转发两层关系。今天我就用Fiddler Classic配合雷电模拟器,把从电脑抓包、设置全局抓包、到抓模拟器流量的完整流程捋一遍。这套组合我用了很久,基本上是调试安卓应用、分析手机接口、排查网络问题的首选方案,开发、测试、安全和网络学习者都能直接参考。
1. HTTPS抓包原理与工具选型
1.1 为什么HTTP能直接抓包,HTTPS却抓不到
HTTP协议是明文传输,抓包工具在中间把请求“看”一遍就行了。HTTPS则不一样,它先通过TLS握手建立加密通道,之后传输的内容全部是密文。你要是直接抓,只能看到TCP层的包,但看不到里面请求了什么参数、返回了什么JSON,因为密钥只有客户端和服务端知道。
抓包工具能解开HTTPS,靠的是“中间人代理”的思路。打个比方:你寄了一个带锁的快递,抓包工具就是中转站。它把你的锁拆了,换上自己的一把锁,再继续发给收件人。收件人以为快递全程只经过自己的手,实际上中转站已经拆开看过里面是什么了。换到技术里,就是抓包工具与客户端建立一条TLS连接,再与服务器建立另一条TLS连接,客户端验证的是抓包工具的证书,服务器验证的也是抓包工具的证书,中间的明文数据自然就全部暴露了。
要做到这一步,必须让客户端信任抓包工具自己的根证书。所以你在电脑或手机上安装抓包工具的证书,不是可选项,而是必选项。如果客户端不信任这个证书,TLS握手会被直接拒绝,表现出来就是“证书错误”“域名不匹配”“SSL错误”之类的提示。
1.2 常见抓包工具横向对比
很多人问我用什么抓包,我的建议是:工具不在多,选顺手的就行。目前主流方案无非这几个:Fiddler Classic、Charles、mitmproxy、Wireshark。它们的侧重点完全不同。
| 工具 | 平台 | 适合场景 | 特点 |
|---|---|---|---|
| Fiddler Classic | Windows | 电脑端、安卓模拟器、浏览器调试 | 免费、脚本功能强、UI信息密度高 |
| Charles | Windows/macOS | 手机真机、macOS开发环境 | 界面清爽、操作直观,但收费 |
| mitmproxy | 跨平台 | 自动化测试、命令行环境 | 基于Python,可编程,需要熟悉命令行 |
| Wireshark | 跨平台 | 底层协议分析、TLS密钥日志 | 能看到网卡所有包,但解密HTTPS需要额外提供密钥 |
这次我用的是Fiddler Classic,主要是因为它在Windows上最省心,安装包小,解密HTTPS只需要勾选一个选项,而且对模拟器流量抓取非常友好。Wireshark虽然底层网络分析更强,但要拿到TLS会话密钥才能解密HTTPS,对抓HTTP/HTTPS接口来说属于“杀鸡用牛刀”。
1.3 为什么选择Fiddler+雷电模拟器这套组合
雷电模拟器是Android模拟器,底层就是一个虚拟机。在模拟器里跑App,本质上和真机没什么区别,所有网络请求会经过虚拟网卡走Wi-Fi。只要我把电脑上的Fiddler作为全局代理开启,然后在模拟器里把网络代理指向电脑,模拟器里所有符合代理配置的HTTP和HTTPS请求都会先经过Fiddler,自然就能解密和分析。
为什么不直接在模拟器里装App抓包?因为很多抓包工具需要root权限、要装证书到系统分区,在模拟器里折腾反而更容易出问题。把抓包这件事剥离出来放到电脑上,好处很明显:界面大、过滤方便、抓包工具卡死了也不影响模拟器里的App继续运行。而且Fiddler的脚本和断点改包功能,比直接在模拟器里操作方便太多。
2. 电脑端HTTPS抓包环境部署
2.1 安装Fiddler并开启全局HTTPS解密
去Fiddler官网下载Fiddler Classic,选Free Download就行,安装过程一路Next,没有太多坑。装完之后打开,第一件事不是急着抓包,而是先把HTTPS解密和远程连接打开。
进入Tools -> Options -> HTTPS,勾选Capture HTTPS CONNECTs和Decrypt HTTPS traffic,下拉框里建议选择... from all processes,这样不管是浏览器、桌面应用还是模拟器发起的HTTPS流量,都会尝试解密。接着切到Connections选项卡,勾选Allow remote computers to connect,代理端口默认是8888,保持默认即可。
这里要理解一下Fiddler的“全局抓包”机制。开启这些选项后,Fiddler会在Windows系统代理里写入一条规则,把电脑上走HTTP/HTTPS的流量转发到127.0.0.1:8888,也就是Fiddler自己身上。所以只要工具开着,浏览器、一些桌面应用都会自动走这个代理。这也是为什么抓包结束后建议及时关闭工具,或者手动关掉系统代理,否则电脑上网体验会受影响。
有个细节要特别说一下:在Tools -> Options -> Connections里有个“Bypass URLs for localhost”之类的选项,不同版本位置略有差异。它的作用是让访问localhost或127.0.0.1的请求不经过代理。如果你要抓本机服务(比如本地启动的接口),记得不要勾选,否则你会在会话列表里看不到任何本地请求。
2.2 安装并信任Fiddler根证书
这一步是解开HTTPS的关键。打开Tools -> Options -> HTTPS,点击Actions -> Trust Root Certificate。系统会弹窗询问是否安装证书,一路选择“是”即可。需要注意,安装位置必须选“受信任的根证书颁发机构”,默认弹窗里一般会帮你选好,如果没有就手动切换。
除了信任到系统根证书,后面给模拟器用的时候还需要把证书导出成文件。在同样的Actions菜单里选择Export Root Certificate to Desktop,桌面就会多出一个FiddlerRoot.cer文件。保存好,后面转换和推送都用得上。
为什么必须在电脑上信任这个证书?因为Fiddler在和浏览器建立HTTPS连接时,会动态生成一个伪造的服务器证书,这个证书是用Fiddler根证书签发的。浏览器出于安全机制,只信任位于系统根证书存储区里的CA,只有当Fiddler根证书被放到那里,浏览器才会认为“这个由Fiddler签发的假证书是合法的”,否则直接报安全异常。
2.3 验证电脑端抓包是否成功
证书装好之后,打开Fiddler,再打开浏览器访问一个HTTPS网站(比如随便一个https开头的站点)。正常情况下,会话列表里会出现两类数据:一类是CONNECT主机名:443,这是初始TLS隧道;另一类是真正的HTTPS请求,双击进去,在Inspectors里能看到完整的请求头、响应头、Cookie、JSON参数。
如果你只看到CONNECT行,点开后没有子请求,说明客户端没有信任Fiddler的证书,或者应用走了其它网络栈。浏览器里常见原因是系统代理被插件覆盖、装了某些广告拦截插件、或者浏览器自带的“安全DNS”干扰。我习惯用浏览器的无痕模式验证,因为无痕模式插件加载少,更容易排除干扰。
验证的时候建议顺便把过滤器清一下。因为Fiddler会抓取所有进程的流量,包括Windows服务、后台更新,看起来会很乱。你可以先点击会话列表上方的X按钮清空内容,再操作目标页面,这样抓到的就是相对干净的请求。
3. 雷电模拟器流量抓包实战
3.1 模拟器代理设置:让流量先走电脑
电脑端准备就绪后,接下来是雷电模拟器。先在模拟器里打开设置,进入WLAN菜单。雷电模拟器一般默认会连上一个叫AndroidWifi的Wi-Fi网络,长按这个网络,选择“修改网络”,把代理方式从“无”改成“手动”。主机名填写电脑在局域网里的IP地址,端口填写8888。
先别急着保存,有几个前置条件必须满足:
- 电脑和模拟器要能互相通信。雷电模拟器默认走NAT网络,理论上模拟器内部可以通过局域网IP访问宿主机,但前提是电脑防火墙允许入站连接。Windows防火墙默认会拦截来自虚拟网卡的外部连接,所以要先放行8888端口。
- 查看电脑IP的方式是命令行输入ipconfig,找到当前网卡的IPv4地址,比如192.168.1.23。不要填127.0.0.1,因为模拟器里的127.0.0.1指向的是模拟器自己,不是你的电脑。
- 保存代理设置后,先在模拟器里打开浏览器访问一个http或https网站,看看是否报网络错误。如果报错,多半是防火墙或IP填写问题。
防火墙放行的操作是:控制面板 -> Windows Defender防火墙 -> 高级设置 -> 入站规则 -> 新建规则 -> 端口 -> TCP -> 特定本地端口8888 -> 允许连接。不同Windows版本可能略有差异,但核心就是把8888端口对模拟器网段打开。
如果实在不想折腾防火墙,还有一个备选:在电脑上打开ADB,执行adb reverse tcp:8888 tcp:8888,把模拟器的8888端口反向映射到电脑的8888端口。然后模拟器代理主机名填127.0.0.1,端口填8888。这个方案走的是ADB通道,不依赖局域网和防火墙,对USB连接的真机也管用,属于紧急救场手段。
3.2 Android 7+的证书信任坑:用户证书不生效
很多人卡在最后一步:模拟器里已经装上了Fiddler证书,抓包工具还是看不到明文,甚至App直接报网络错误。这个问题几乎都出在Android 7.0之后的一个安全变更上。
从Android 7开始,系统默认不再信任用户安装的证书,只有放在系统分区里的证书才被App信任。虽然你在模拟器设置里“安装证书”能成功,但对于绝大多数Android 7+应用来说,这个证书形同虚设,因为它们只信任系统CA证书。
解决办法是把Fiddler证书变成系统证书。大致流程如下:
先将导出的FiddlerRoot.cer从DER格式转换成系统证书要求的文件名。证书文件名不是随便起的,而是根据证书主题哈希值生成的。Windows上可以用openssl命令,Linux或macOS同理。
openssl x509 -inform DER -in FiddlerRoot.cer -subject_hash_old -noout执行后会输出一串十六进制字符,比如87c0d856。然后把这个证书文件重命名为87c0d856.0。
接下来用ADB把证书推送到模拟器的系统证书目录。雷电模拟器需要先开启Root权限,在模拟器设置里打开“Root权限”开关,然后重启模拟器。
adb connect 127.0.0.1:5555 adb root adb remount adb push 87c0d856.0 /system/etc/security/cacerts/ adb shell chmod 644 /system/etc/security/cacerts/87c0d856.0执行完后重启模拟器,或至少重启目标App,再去Fiddler里看,大多数HTTPS流量都能解开明文了。
如果你觉得push到系统目录太折腾,还有一个偷懒的办法:多开一个Android 5.1的雷电模拟器专门用来抓包。低版本系统对证书信任更宽松,很多App用低版本系统调试时不会校验那么严格。不过对于新版本App来说,最低兼容版本往往也要求Android 7以上,所以这个偷懒方案并不总能成功。
3.3 真机与模拟器抓包的差异与取舍
标题里还提到抓手机流量,这里一并说清楚。真机和模拟器的抓包思路几乎一样,都是让手机连上电脑所在Wi-Fi,手动设置HTTP代理指向电脑IP:8888,再安装根证书。区别在于:苹果和部分安卓真机安装证书后,还需要在系统设置里手动信任这个证书,否则同样抓不到明文。
模拟器相对更方便的一点是,你可以自由创建不同Android版本的多开实例,而且随时可以重置系统,不怕把环境搞坏。真机则更贴近真实网络环境,适合测试弱网、定位GPS、相机等硬件相关场景,但证书安装步骤会多一些。
我的建议是:抓App接口、调试模拟器里的应用,优先用雷电模拟器;测真实网络、验权限弹窗、做弱网测试,再过渡到真机。两者在抓包原理上没有本质区别,前面这套电脑端Fiddler配置完全可以共用。
4. 流量过滤与接口调试技巧
4.1 快速定位目标请求
代理设置完成之后,Fiddler会哗啦啦抓到大量请求。如果你不加以过滤,很容易在一堆图片、统计、上报请求里迷失方向。这时候有几个非常实用的过滤办法。
最简单的是用QuickExec命令行,也就是Fiddler底部的黑色输入框。输入?加关键字,可以过滤出URL中包含该关键字的请求,比如?api;输入host:api.example.com可以只显示某个域名的请求;输入/login能过滤出路径中包含login的请求。这种方式快,而且不用点点点。
如果要做更精细的过滤,右上角Filters选项卡更好用。勾选Use Filters后,可以按Host、Request Headers、Response Status Code等维度过滤。我常用的组合是:只显示某个Host、且响应码为200-302的请求。这样基本能滤掉绝大多数噪声。
还有一个习惯:在点开App某个页面之前,先在Fiddler里按Ctrl+X清空所有会话,然后在模拟器里操作,最后回到Fiddler看新产生的请求。这样抓到的就是这次操作的完整请求链路,定位问题非常高效。
4.2 断点修改请求和响应
抓包不只是“看”,更实用的是“改”。Fiddler支持在请求发送前和响应返回后打断点,你可以在断点处修改数据,再放行。这个功能在调试接口兼容性、模拟异常响应、绕过前端校验时特别有用。
设置方式很简单:菜单Rules -> Automatic Breakpoints -> Before Requests,表示所有请求在发出去之前会被拦截;After Responses则会在响应返回给客户端之前拦截。你也可以用快捷键F11切换请求前断点,Alt+F11切换响应后断点。
举个例子:某个接口返回的列表默认只有10条数据,我想验证前端能不能正确渲染500条。那就可以在After Responses模式下,双击这个接口的响应报文,把返回JSON里分页大小字段从10改成500,再点击Run to Completion放行。App端就能看到对应的UI变化。
改包只能用于你自己有权限测试的系统。如果是在未经授权的环境里篡改线上接口的返回,那性质就变味了。千万别拿这个功能去薅羊毛、改支付结果、绕过会员验证,我这里只聊正规调试场景。
4.3 通过明文报文排查接口问题
抓包最实在的价值,就是把HTTPS解密成明文后,详细分析一次请求链路。我习惯按这个顺序检查:
- 请求行:URL、请求方法、HTTP版本。
- 请求头:User-Agent、Content-Type、Cookie、Authorization。
- 请求体:表单参数、JSON参数、二进制上传数据。
- 响应状态码:200、400、401、403、500等。
- 响应体:JSON、XML、HTML、图片流。
有一次我遇到一个接口返回400错误,抓包发现请求体里某个字段传了null,但服务端要求传字符串,这就是典型的参数类型不匹配。如果没有抓包,光看错误码你只能瞎猜。抓包后你再对比正常请求和异常请求的报文差异,问题基本一眼就能看出来。
Fiddler的Inspectors面板提供了很友好的查看方式。顶部是请求相关数据,底部是响应相关数据,JSON数据会自动格式化,比直接看原始报文舒服很多。如果你需要在多个请求之间比较,可以选中两条会话,用Ctrl+鼠标多选,再对比Headers或Body差异。
5. 常见问题与避坑指南
5.1 问题速查表
下面这些是使用Fiddler+雷电模拟器抓包时最常见的几个问题,我按“现象-原因-处理”整理成了速查表,方便你直接对照排查。
| 现象 | 可能原因 | 处理方法 |
|---|---|---|
| 模拟器设置代理后无法上网 | 代理IP写错,或防火墙未放行8888端口 | 检查电脑IP,确认防火墙入站规则 |
| Fiddler只能看到CONNECT隧道,看不到请求 | 客户端未信任Fiddler根证书 | 重新安装并信任根证书,模拟器转系统证书 |
| App提示SSL证书错误 | Android 7+不信任用户证书 | 按3.2节将证书推送进系统证书目录 |
| 抓到的全是模拟器系统流量,App没流量 | App可能走UDP/QUIC或自有协议 | 确认App是否使用HTTP/HTTPS,或是否禁用代理 |
| 电脑浏览器能抓,模拟器里抓不到 | 模拟器代理未保存,或代理字段被App忽略 | 重新配置代理,必要时用adb reverse |
| Fiddler抓不到localhost本地服务 | “Bypass localhost”选项被勾选 | 在Connections选项中取消绕过localhost |
| 抓包后电脑网络异常 | Fiddler关闭时未还原系统代理 | 退出Fiddler后检查系统代理设置 |
5.2 我踩过的几个坑
第一个大坑是防火墙。我最初配置模拟器代理时,怎么填IP都不通,模拟器浏览器一直提示网络异常。后来才发现Windows防火墙默认把入站端口全拦了,给8888端口加一条放行规则就好了。这个问题极其隐蔽,因为电脑本机访问Fiddler完全正常,容易让人误以为是模拟器本身的问题。
第二个坑是证书格式和文件名。生成系统证书时,很多人直接把导出的cer文件push进去,文件名还是FiddlerRoot.cer,这当然不行。系统读取证书是按文件名哈希来索引的,文件名不对就不认。记住先执行openssl命令算哈希,再重命名成<哈希>.0。
第三个坑是那些带SSL Pinning的应用。这类应用会在客户端内置服务器公钥或证书指纹,不管你装什么根证书,它都只认自己内置的那一套。抓不到是正常的,不代表你哪里做错了。如果是自己团队的应用,可以让开发加个调试开关关闭Pinning;如果是第三方应用,请先确认你是否有合法授权。
第四个坑是模拟器网络模式。雷电模拟器默认NAT和桥接模式在某些版本下代理表现不太一样。如果配好代理后依旧不通,试着去模拟器设置里切换一下网络模式,或者重启模拟器让网络配置重新加载。不要在同一界面反反复复改,很容易产生延迟。
5.3 合规提醒
最后想多说一句:抓包能力强不强不重要,重要的是用在什么地方。整个抓包流程只适用于你自己拥有的设备、你自己开发的应用,或者你明确获得授权的系统测试。不要拿这套技术去截取别人的通信内容,不要在公共环境下随意抓包,更不要试图绕过支付验证、会员权限这类安全机制。网络安全的立足点是保护系统,而不是破坏系统。把这套技能用在调试自己的接口、分析自己的App、学习网络原理上,才是正确的打开方式。
我个人实际用下来的体会是,抓包这类问题,90%都出在证书信任和代理连通性上。遇到抓不到包,不要先怀疑工具不行,按“系统代理是否生效 -> 根证书是否被信任 -> 目标App是否校验代理/TLS”这个顺序排查,绝大部分问题十分钟内就能定位。这套Fiddler+雷电模拟器的组合我一直在用,稳定性够,可自定义程度也高。等你熟练之后,可以再接触mitmproxy脚本化抓包,把请求自动保存、自动断言都跑起来,那又是另一个层次的高效了。