Android

targetSDKを24以上にしたところ、AndroidでSSL通信ができなくなった

android_network

この間(2018年10月ごろ)、アプリのtargetSDKを26にあげる作業を行いました。
今後の Google Play でのアプリのセキュリティおよびパフォーマンスの改善について」への対応です。

その後、アプリの動作確認をしていたところ、7系や8系の端末でSSL通信が失敗するようになりました。

確認したところ、Android7.0(APIレベル24)を境に、ネットワークのセキュリティ構成が変更になっていたのですね。
参考:Has Android changed SSL configuration in API 24?

今まではtargetSDKがもっと低かったので気づきませんでした。
設定を追加したところ、正常に接続できるようになりました。

今回は、その際に調べた内容についてご紹介します。

Android7.0でのセキュリティに関する変更について

Android7.0では、Androidが認証局を扱う際の方法が変更になりました。
今まではデフォルトの状態で、ユーザーが追加した認証局を信頼してくれていたのですが、この変更により、デフォルト設定ではユーザーや管理者が追加した認証局は信頼しないようになりました。

詳細は以下の記事をご確認ください。
Android Nougat における認証局の変更

また、信頼できる認証局の設定方法が変更になりました。
res/xml/network_security_config.xml というセキュリティ構成ファイルに直接設定を追加することができるため、今までよりもわかりやすくなったと言えます。

network_security_config.xmlの設定の仕方

network_security_config.xmlを設定するには、Androidマニフェストに以下のように追加します。

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:networkSecurityConfig="@xml/network_security_config"
                    ... >
    </application>
</manifest>

そして、network_security_config.xmlを作成しましょう。

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <!— 特定のドメインだけ許可したい場合 —>
    <domain-config>
        <domain includeSubdomains="true">internal.example.com</domain>
        <trust-anchors>
            <certificates src="@raw/trusted_roots"/>
        </trust-anchors>
    </domain-config>
      <!— 特定のドメイン以外に対して認証局を信頼する場合 —>
      <base-config>  
           <trust-anchors>  
                <certificates src="system" />  
                <certificates src="user" />  
           </trust-anchors>  
      </base-config>  
</network-security-config>

domain-configは、固有の接続先への接続に対して使用される設定になります。
base-configは、domain-configに含まれないすべての接続先への接続に使用されるデフォルトの設定です。

このようにすれば接続できると思います。
うまくいかない場合は公式ドキュメントをご確認いただき、用途に応じて調整してください。

終わりに

近年のAndroidのアップデートはセキュリティ周りを強く意識していますね。
セキュリティ向上の流れに乗り遅れないよう、情報をしっかりと収集していこうと思います。
以上です。それでは。