當(dāng)我們將App的targetSdkVersion升級到API 24以后誊爹,在Android 7.0(API 24)以上的手機(jī)就會出現(xiàn)無法抓取HTTPS請求的問題,所有的請求都會顯示為Unknown赴捞。
原因:
在targetSdkVersion選擇適配24后,API 24的平臺默認(rèn)值被變更了郁稍,在API 24以上的App默認(rèn)不信任用戶證書(trust-anchors
里沒有了<certificates src="user" />
這一行)赦政,因此我們使用Charles進(jìn)行抓包時(shí),安裝的Charles證書就不起作用了耀怜,App不信任我們的證書恢着,導(dǎo)致無法進(jìn)行中間人攻擊(抓包原理),因此無法抓包财破。
平臺默認(rèn)配置如下所示:
未設(shè)置的任何值均使用平臺默認(rèn)值掰派。面向 Android 7.0(API 級別 24)及更高版本應(yīng)用的默認(rèn)配置如下所示:
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
面向 Android 6.0(API 級別 23)及更低版本應(yīng)用的默認(rèn)配置如下所示:
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</base-config>
Note:
1.系統(tǒng)證書是系統(tǒng)內(nèi)置的證書鏈,用戶證書是用戶安裝的自信任證書左痢。
2.為啥說Root的手機(jī)沒有安全性保證靡羡,因?yàn)镽oot過后的手機(jī)什么都能改,包括把網(wǎng)絡(luò)攻擊者的證書安裝成為系統(tǒng)證書俊性。
解決方法:
如果單純地在Manifest里制定的文件中改成API 23以下的默認(rèn)設(shè)置略步,那么Google為我們帶來的安全性變更則不復(fù)存在,但當(dāng)我們復(fù)寫平臺默認(rèn)配置的情況下定页,則6.0以下的手機(jī)也不能進(jìn)行抓包趟薄!安全性大大提高,平臺默認(rèn)配置的復(fù)寫配置在AndroidManifest.xml文件中典徊。
AndroidManifest的網(wǎng)絡(luò)配置如下所示:
android:networkSecurityConfig="@xml/network_security_config"
如果在這個(gè)配置的基本配置項(xiàng)base-config
里改成API 23以下的默認(rèn)配置杭煎,即相信用戶證書的話恩够,那相當(dāng)于將安全性倒退到6.0之前,但我們可以實(shí)現(xiàn)只有在打debug包時(shí)才允許抓包岔帽,在打release發(fā)布包時(shí)玫鸟,不允許抓包。這里就需要用到一個(gè)配置debug-overrides
//android:debuggable="true"時(shí)復(fù)寫的配置犀勒,信任系統(tǒng)/用戶證書
//跟應(yīng)用是否簽名沒關(guān)系屎飘,如果希望打包給服務(wù)端同學(xué)一個(gè)可抓包的包,構(gòu)建prodDebug就可以贾费,
//正式發(fā)布構(gòu)建的是prodRelease钦购,無法抓包。
<debug-overrides>
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</debug-overrides>
所以最終的配置文件會長下面這樣子褂萧,就實(shí)現(xiàn)了在android:debuggable="true"
的情況下(通過Android Studio的直接安裝 or 通過Gradle的assebleDebug
)應(yīng)用可以抓包押桃。通過這個(gè)方式我們可以快速提供給服務(wù)端同學(xué)&測試同學(xué)可以抓包的App。
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
//文檔見:https://developer.android.com/training/articles/security-config?hl=zh-cn
//https://developer.android.com/reference/android/security/NetworkSecurityPolicy.html?hl=zh-cn#isCleartextTrafficPermitted()
//Android 7以上的默認(rèn)配置导犹,默認(rèn)只信任系統(tǒng)證書/允許明文通信
//cleartextTrafficPermitted意思是允許明文通信唱凯,設(shè)置為false的話會在明文通信時(shí)退出app
//NOTE: WebView honors this flag for applications targeting API level 26 and up.
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
//android:debuggable="true"時(shí)復(fù)寫的配置,信任系統(tǒng)/用戶證書
//跟應(yīng)用是否簽名沒關(guān)系谎痢,如果希望打包給服務(wù)端同學(xué)一個(gè)可抓包的包磕昼,構(gòu)建prodDebug就可以,
//正式發(fā)布構(gòu)建的是prodRelease节猿,無法抓包票从。
<debug-overrides>
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</debug-overrides>
</network-security-config>
復(fù)寫平臺默認(rèn)配置好處:
原本我們的app在6.0以下的手機(jī)也能被抓包,但當(dāng)我們復(fù)寫了以后滨嘱,6.0以下的手機(jī)也不能進(jìn)行抓包了峰鄙,但是我們還是可以方便地構(gòu)造出可以抓包的debug包,安全調(diào)試兩不誤太雨!
注意:
cleartextTrafficPermitted
是允許明文通信的意思吟榴,這個(gè)不要隨便設(shè)置為false
,設(shè)置為false
意思是不允許明文通信囊扳,當(dāng)服務(wù)端把HTTPS改成HTTP的時(shí)候你的App發(fā)生請求時(shí)就自動退出了煤墙,跟閃退差不多。
isCleartextTrafficPermitted() ==> NOTE: WebView honors this flag for applications targeting API level 26 and up.
當(dāng)應(yīng)用以API 26及以上為適配目標(biāo)時(shí)WebView會遵循這個(gè)標(biāo)志位宪拥。
原文中有這么一句注釋仿野,意思是當(dāng)targetSdkVersion在26以上的話,如果不允許明文通信而WebView使用了明文通信的話她君,程序也會退出脚作。
參考鏈接
谷歌官方文檔-網(wǎng)絡(luò)安全性配置
是否允許明文通信isCleartextTrafficPermitted()