當(dāng)我們將App的targetSdkVersion升級(jí)到API 24以后,在Android 7.0(API 24)以上的手機(jī)就會(huì)出現(xiàn)無(wú)法抓取HTTPS請(qǐng)求的問題,所有的請(qǐng)求都會(huì)顯示為Unknown。
原因:
在targetSdkVersion選擇適配24后,API 24的平臺(tái)默認(rèn)值被變更了,在API 24以上的App默認(rèn)不信任用戶證書(trust-anchors里沒有了<certificates src="user" />這一行),因此我們使用Charles進(jìn)行抓包時(shí),安裝的Charles證書就不起作用了,App不信任我們的證書,導(dǎo)致無(wú)法進(jìn)行中間人攻擊(抓包原理),因此無(wú)法抓包。
平臺(tái)默認(rèn)配置如下所示:
未設(shè)置的任何值均使用平臺(tái)默認(rèn)值。面向 Android 7.0(API 級(jí)別 24)及更高版本應(yīng)用的默認(rèn)配置如下所示:
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
面向 Android 6.0(API 級(jí)別 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為我們帶來(lái)的安全性變更則不復(fù)存在,但當(dāng)我們復(fù)寫平臺(tái)默認(rèn)配置的情況下,則6.0以下的手機(jī)也不能進(jìn)行抓包!安全性大大提高,平臺(tái)默認(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,無(wú)法抓包。
<debug-overrides>
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</debug-overrides>
所以最終的配置文件會(huì)長(zhǎng)下面這樣子,就實(shí)現(xiàn)了在android:debuggable="true"的情況下(通過Android Studio的直接安裝 or 通過Gradle的assebleDebug)應(yīng)用可以抓包。通過這個(gè)方式我們可以快速提供給服務(wù)端同學(xué)&測(cè)試同學(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的話會(huì)在明文通信時(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,無(wú)法抓包。
<debug-overrides>
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</debug-overrides>
</network-security-config>
復(fù)寫平臺(tái)默認(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ā)生請(qǐng)求時(shí)就自動(dòng)退出了,跟閃退差不多。
isCleartextTrafficPermitted() ==> NOTE: WebView honors this flag for applications targeting API level 26 and up.
當(dāng)應(yīng)用以API 26及以上為適配目標(biāo)時(shí)WebView會(huì)遵循這個(gè)標(biāo)志位。
原文中有這么一句注釋,意思是當(dāng)targetSdkVersion在26以上的話,如果不允許明文通信而WebView使用了明文通信的話,程序也會(huì)退出。
參考鏈接
谷歌官方文檔-網(wǎng)絡(luò)安全性配置
是否允許明文通信isCleartextTrafficPermitted()