對於以前的文章: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源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。