对于以前的文章:Fiddler对安卓App抓包(逍遥模拟器APP)
java
可是,升级了 targetSdkVersion 到 28 后发如今 Android 7.0 以上机型 Charles 抓取 https 包时显示找不到证书,可是 Android 6.0 机型仍是能够正常抓包。缘由是由于从 Android 7.0 开始,默认的网络安全性配置修改了android
解决方法以下:
web
现象:android7.0以上的手机https抓包失败(安装了https证书也不行)
缘由:android7.0+的版本新增了证书验证(系统证书),具体以下:
一、Android 6.0(API 23)及更低版本应用的默认网络安全性配置以下:sql
<!-- 默认容许全部明文通讯 --><base-config cleartextTrafficPermitted="true"> <trust-anchors> <!-- 信任系统预装 CA 证书 --> <certificates src="system" /> <!-- 信任用户添加的 CA 证书,Charles 和 Fiddler 抓包工具安装的证书属于此类 --> <certificates src="user" /> </trust-anchors></base-config>
二、而在 Android 7.0(API 24)到 Android 8.1(API 27)的默认网络安全性配置以下:安全
<!-- 默认容许全部明文通讯 --><base-config cleartextTrafficPermitted="true"> <trust-anchors> <!-- 信任系统预装 CA 证书 --> <certificates src="system" /> </trust-anchors></base-config>
三、而在 Android 9.0(API 28)及更高版本的默认网络安全性配置以下:微信
<!-- 默认禁止全部明文通讯 --><base-config cleartextTrafficPermitted="false"> <trust-anchors> <!-- 信任系统预装 CA 证书 --> <certificates src="system" /> </trust-anchors></base-config>
对比很容易发现,在 Android 7.0(API 24)到 Android 8.1(API 27),默认再也不信任用户添加的 CA 证书,因此也就再也不信任 Charles 和 Fiddler 抓包工具的证书,因此抓取 HTTPS 包时才会失败。并且在 Android 9.0(API 28)及更高版本上,不只默认只系统预装的 CA 证书,还默认禁止全部明文通讯(不容许 http 请求)。网络
解决办法:
前提:在手机端和电脑端都必须安装https的安全证书
配置:打测试包时,项目设置默认信任全部证书(系统+用户,Charles 和 Fiddler)
1. 在工程res-xml目录中建立一个名为 network_security_config.xml的文件,文件内容以下:架构
<network-security-config> <base-config cleartextTrafficPermitted="true"> <trust-anchors> <certificates src="system" overridePins="true" /> <certificates src="user" overridePins="true" /> </trust-anchors> </base-config></network-security-config>
2.在AndroidManifest里的
<manifest ... ><application android:networkSecurityConfig="@xml/network_security_config"... > ...</application></manifest>
从新打包项目,而后抓包,便可成功。dom
webview抓包失败
上面能够解决android原生抓包问题,但在android7.0以上的手机,开着网络代理访问不了webview,若要抓包webview,
须要在webview的WebViewClient中,将一行代码给注释掉:
super.onReceivedSslError(view, handler, error)
这样是为了忽略掉SSL证书错误,由于开启代理后网络会变得不安全,证书会报错误,webview检测到证书错误以后就不请求任何数据。注释是为了忽略掉父类的处理,默认执行下去。
警告
这样的配置操做是敏感且危险的,只能用于测试环境方便抓包,线上包必定注意要恢复配置,否则APP会面临被他人抓包的风险。
如何只在调试模式下容许抓包呢?
使用<debug-overrides>
便可实现只在android:debuggable
为true
时才生效的配置:
<network-security-config> <!-- 支持 Android 7.0 以上调试时,信任 Charles 和 Fiddler 等用户信任的证书 --> <debug-overrides> <trust-anchors> <certificates src="system" /> <certificates src="user" /> </trust-anchors> </debug-overrides></network-security-config>
网上有些解决方式是将 Charles 和 Fiddler 的证书添加到raw
文件夹下的方式也能够,可是繁琐了点。
在 Android 9.0(API 28)以上容许部分 http 请求
最佳的解决方式确定是所有使用 https 请求,安全性更高,若是有些请求或测试环境下仍是须要使用 http 请求,须要在网络安全性配置添加白名单:
<network-security-config> <!-- 支持 Android 9.0 以上使用部分域名时使用 http --> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">sample.domain</domain> </domain-config> <!-- 支持 Android 7.0 以上调试时,信任 Charles 和 Fiddler 等用户信任的证书 --> <debug-overrides> <trust-anchors> <certificates src="system" /> <certificates src="user" /> </trust-anchors> </debug-overrides></network-security-config>
后记
经过查找资料,还有一个方法,经过重载WebViewClient的onReceivedSslError()函数并在其中执行handler.proceed(),便可忽略SSL证书错误,继续加载页面,代码以下:
WebView webview = (WebView) findViewById(R.id.webview);webview.setWebViewClient(new WebViewClient() {public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {// 不要调用super.onReceivedSslError,由于其包含了一条 handler.cancel(),第一次访问时没法加载,第二次之后能够加载// super.onReceivedSslError(view, handler, error);// 忽略SSL证书错误,继续加载页面 handler.proceed(); }}
以上内容参考:流柯 和 JohnnyShieh 的博客
软件(自动化)测试微信交流群
欢迎入群
文章合集
Selenium | Appium | Jenkins | Jmeter
软件测试方法汇总 | Postman接口参数化 | 测试用例设计
视频教程
Selenium | Appium | Jenkins | Jmeter
AWS与Docker
如何使用AWS EC2+Docker+JMeter构建分布式负载测试基础架构
Docker容器数据持久化和容器网桥链接
Docker删除image和container
Docker与VM虚拟机的区别以及Docker的特色
END
以为不错,能够“点赞”和“在看”,或者转发、留言
精彩的内容要和朋友分享哦
本文分享自微信公众号 - 软测小生(ruancexiaosheng)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。