Android 項目網絡安全配置知識記錄

Android 項目網絡安全配置知識記錄

Android 在 Android 9(Pie)[android:targetSdkVersion = 28]以後將網絡通訊默認配置爲禁止了明文傳輸。所謂明文傳輸就是Http請求,因此若是咱們開發版本高於 28 ,打包以後咱們 app 中的 Http 請求都沒法成功,將會拋出java

W/System.err: java.net.UnknownServiceException: CLEARTEXT communication to **** not permitted by network security policy
複製代碼

的錯誤。android

關於 Http 請求的限制歷史:

  • 當 Android 6.0(Marshmallow)「(API 23)」發佈時,谷歌提出了清單文件中配置: android:usesCleartextTraffic 做爲防止意外使用明文通訊的手段
<!-- 默認容許全部明文通訊 -->
<base-config cleartextTrafficPermitted="true">
    <trust-anchors>
        <!-- 信任系統預裝 CA 證書 -->
        <certificates src="system" />
        <!-- 信任用戶添加的 CA 證書,Charles 和 Fiddler 抓包工具安裝的證書屬於此類 -->
        <certificates src="user" />
    </trust-anchors>
</base-config>
複製代碼
  • Android 7.0 (Nougat) 經過引入Android網絡安全配置 「Network Security Configuration」特性來過渡開發者配置這個屬性。Android 7.0 ~ 8.0 「(API 24) 至 (API 27)」 之間,客戶端仍可使用 Http 請求。系統默認網絡安全配置以下
<!-- 默認容許全部明文通訊 -->
<base-config cleartextTrafficPermitted="true">
    <trust-anchors>
        <!-- 信任系統預裝 CA 證書 -->
        <certificates src="system" />
    </trust-anchors>
</base-config>
複製代碼
  • Android 9(Pie)「(API 28)」之後系統默認強制禁止明文傳輸 usesCleartextTraffic = true 且默認只信任系統級別證書,也就是咱們在手機,設置-> 加密與憑據 ->信任的憑據 -> 系統tab下的全部證書。
<!-- 默認禁止全部明文通訊 -->
<base-config cleartextTrafficPermitted="false">
    <trust-anchors>
        <!-- 信任系統預裝 CA 證書 -->
        <certificates src="system" />
    </trust-anchors>
</base-config>
複製代碼

網絡安全配置對咱們開發者的影響

若是咱們採用默認配置,在咱們升級 targetSdkVersion >= 24 後,咱們就會遇到 Https 請求沒法經過抓包工具配置的證書進行抓包的問題。git

當咱們升級 targetSdkVersion >= 28 就會出現沒法全部的 Http 請求都沒法響應的問題。github

經過上一節網絡配置版本變化的描述過程咱們會發現,緣由在於,24 以上再也不信任用戶證書了因此抓不了包了,28 以上沒法進行http請求的緣由是,系統默認不讓進行明文傳輸了。安全

什麼是網絡安全配置?

上面解釋了這麼配置就能夠解決咱們遇到的沒法抓包和沒法進行http請求的問題,咱們大概能夠理解爲這個「網絡安全配置」其實就是駕馭在代碼以外的一個配置文件,程序讀取配置來決定要不要校驗http請求,是否是信任用戶證書。bash

能夠看出 google 雖然作了限制,可是也給了開發者自由。接下來就要憑着開發者的良心辦事情了。服務器

「最佳」實踐

固然爲了響應 Google 爸爸的要求和用戶信息安全考慮,咱們應該儘快升級全部的服務器域名爲 Https 請求。可是對於有時候咱們仍是有一些域名爲 Http 請求沒法及時替換,就須要單獨配置了。並且就正式的 APP 包,咱們並不但願可讓其餘人抓包,來給咱們服務器帶來安全隱患。網絡

容許明文傳輸

  • 方法一

容許明文傳輸有兩種配置方法第一個是在項目的主 module 的 AndroidManifest.xml 的 application 節點下配置app

<application
        ...
        <!--容許 -->
        android:usesCleartextTraffic="true"
        ...>
        ...
</application>
複製代碼

可是這個屬性在 Android 7.0 之後會被 android:networkSecurityConfig 屬性覆蓋。dom

  • 方法二

添加在主工程中配置 res/xml/network_security_config.xml 若是沒有能夠新建一個文件。該配置會覆蓋系統默認配置。因此咱們可在這裏配置咱們本身的想要的網絡配置。配置完成後咱們須要在 AndroidManifest.xml 的 application 節點下配置

<application
        ...
            <application android:networkSecurityConfig="@xml/network_security_config"
            <!--7.0後會被覆蓋-->
        <!--android:usesCleartextTraffic="true"--> 
        ...>
        ...
</application>
複製代碼
  • 如何配置 network_security_config

可包含:

0 或 1 個 <base-config>基本配置,也就是默認配置。 任意數量的 <domain-config> 能夠規定任意域名的請求配置 0 或 1 個 <debug-overrides> debug 模式下域名的配置,可用於調試下進行一些獨立配置。

若是咱們須要只須要支持某些域名下的明文傳輸,就能夠利用 domain-config 來進行單獨配置

<network-security-config>
    <!--容許有多個 domain-confing 該domain-config 下的domain 域名容許明文傳輸-->
    <domain-config cleartextTrafficPermitted="true">
        <!--includeSubdomains 是不是包含子域名-->
        <domain includeSubdomains="true">example.com</domain>
        <domain includeSubdomains="true">cdn.example2.com</domain>
    </domain-config>
    <!--除了domain-config 的標籤下的域名都不容許明文傳輸-->
    <base-config cleartextTrafficPermitted="false" />
</network-security-config>
複製代碼

信任用戶證書

好比咱們須要容許debug模式下容許抓包,也就是信任 user 證書能夠進行下面的配置

<network-security-config>
    <!-- 支持 Android 7.0 以上調試時,信任 Charles 等抓包工具的證書 -->
    <debug-overrides>
            <trust-anchors>
                <certificates src="system" />
                <certificates src="user" />
            </trust-anchors>
    </debug-overrides>
    ...
</network-security-config>
複製代碼

對於更多的配置信息你們能夠參照google文檔:網絡徹底配置 一節。

在解決網絡徹底配置的時候忽然想到了 Https 證書驗證的問題,爲何咱們APP本地沒有安裝證書,使用 OkHttp 也不用忽略證書驗證,一樣訪問大多數網站的時候咱們也都沒有下載證書。就能夠訪問了。實際上是由於 OkHttp 對於經過CA機構頒發的服務器證書,是默認經過校驗的。一些公司的自簽名證書就不行了。好比 12306。

#參考

相關文章
相關標籤/搜索