page.title=ネットワーク セキュリティ構成 page.keywords=androidn,security,network page.image=images/cards/card-nyc_2x.jpg @jd:body
Android N には、ネットワーク セキュリティ構成機能が含まれています。これにより、アプリのコードを修正しなくても、安全な宣言型構成ファイルで、アプリのネットワーク セキュリティの設定をカスタマイズできます。 これらの設定は、特定のドメインおよび特定のアプリに対して構成できます。 主な機能は次のとおりです。
ネットワーク セキュリティ構成機能は、XML ファイルを使用します。このファイルで、アプリの設定を指定できます。 アプリのマニフェストに、このファイルを指すエントリを含める必要があります。 次のコードはマニフェストからの抜粋で、このエントリの作成方法を示しています。
<?xml version="1.0" encoding="utf-8"?> <manifest ... > <application ... > <meta-data android:name="android.security.net.config" android:resource="@xml/network_security_config" /> ... </application> </manifest>
アプリで、プラットフォームのデフォルトの設定ではなく、カスタマイズした一連の CA を信頼することが必要な場合があります。 主な理由は次のとおりです。
デフォルトで、すべてのアプリのセキュアな接続(TLS、HTTPS など)は、システムにプレインストールされた CA を信頼し、API レベル 23(Android M)以下をターゲットにしたアプリは、ユーザーが追加した CA も信頼します。 アプリは {@code base-config}(アプリ全体のカスタマイズ)または {@code domain-config} (ドメイン単位のカスタマイズ)を使用して、独自の接続をカスタマイズすることもできます。
自己署名 SSL 証明書を使用するホストか、または信頼できる非パブリック CA(社内の CA など)によって SSL 証明書が発行されているホストに接続するケースで説明します。
res/xml/network_security_config.xml
:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config> <domain includeSubdomains="true">example.com</domain> <trust-anchors> <certificates src="@raw/my_ca"/> </trust-anchors> </domain-config> </network-security-config>
PEM または DER 形式で、自己署名または非パブリック CA 証明書を {@code res/raw/my_ca} に追加します。
システムによって信頼されているすべての CA をアプリで信頼したくない場合は、信頼する CA を制限できます。 これにより、他の CA が発行した偽造証明書からアプリを保護できます。
信頼できる CA を制限するための設定は、特定のドメインでカスタムの CA を信頼する設定と似ています。ただし、リソースで複数の CA を指定できる点が異なります。
res/xml/network_security_config.xml
:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config> <domain includeSubdomains="true">secure.example.com</domain> <domain includeSubdomains="true">cdn.example.com</domain> <trust-anchors> <certificates src="@raw/trusted_roots"/> </trust-anchors> </domain-config> </network-security-config>
PEM または DER 形式で、信頼できる CA を {@code res/raw/trusted_roots} に追加します。
PEM 形式を使用する場合、そのファイルには PEM データのみを含めるようにして、余分なテキストを含めないでください。
1 つだけでなく複数の
<certificates>
要素を指定できます。
システムで信頼されていない CA を、アプリが追加で信頼しなければならない場合があります。これは、システムに CA がまだ組み込まれていなかったり、CA が Android システムに組み込まれるための要件を満たしていないことが原因です。 CA を追加するには、アプリの構成で複数の証明書ソースを指定します。
res/xml/network_security_config.xml
:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config> <trust-anchors> <certificates src="@raw/extracas"/> <certificates src="system"/> </trust-anchors> </base-config> </network-security-config>
HTTPS で接続するアプリをデバッグするときは、運用サーバーの SSL 証明書がインストールされていないローカルの開発サーバーへの接続が必要になります。 アプリのコードを変更せずにこの接続をサポートするには 、 {@code debug-overrides} を使用して、android:debuggable が {@code true} の場合にのみ信頼されるデバッグ限定の CA を指定できます。 通常、IDE およびビルド ツールによって、非リリース ビルドには自動的にこのフラグが設定されます。
この方法は、通常の条件付きコードよりも安全です。セキュリティ対策として、アプリ ストアでは debuggable とマークされたアプリは拒否されるからです。
res/xml/network_security_config.xml
:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <debug-overrides> <trust-anchors> <certificates src="@raw/debug_cas"/> </trust-anchors> </debug-overrides> </network-security-config>
アプリケーションで、セキュアな接続のみを使用して接続する場合、それらの接続先に対して(HTTPS ではなく暗号化されていない HTTP プロトコルを使用する)クリアテキストのサポートを除外できます。 このオプションにより、バックエンド サーバーなど外部ソースが提供する URL の変更によって、アプリで思わぬパフォーマンスの低下が発生するのを防ぐことができます。 詳細については、{@link android.security.NetworkSecurityPolicy#isCleartextTrafficPermitted NetworkSecurityPolicy.isCleartextTrafficPermitted()} をご覧ください。
たとえば、アプリで {@code secure.example.com} へのすべての接続には常に HTTPS を使用して、機密性の高いトラフィックを有害なネットワークから保護することが必要な場合があります。
res/xml/network_security_config.xml
:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config usesCleartextTraffic="false"> <domain includeSubdomains="true">secure.example.com</domain> </domain-config> </network-security-config>
通常、アプリはプレインストールされたすべての CA を信頼します。これらの CA が偽造証明書を発行すると、アプリは MiTM 攻撃のリスクにさらされます。 アプリによっては、信頼する CA を制限するか証明書をピン留めすることで、受け入れる証明書を制限できます。
証明書をピン留めするには、公開鍵のハッシュによって証明書のセットを指定します(X.509 証明書の SubjectPublicKeyInfo)。 証明書チェーンが有効になるのは、証明書チェーンに 1 つ以上のピン留めされた公開鍵が含まれている場合のみです。
証明書のピン留めを使用するときは、必ずバックアップの鍵を含めてください。そうすれば、新しい鍵に切り替えたり、CA を変更したりする必要が生じた場合に(CA 証明書またはその CA の中間証明書にピン留めしていても)、アプリの接続が影響を受けることはありません。 そうしないと、接続を復元するためにアプリにアップデートをプッシュしなければならなくなります。
また、ピン留めの有効期限を設定することもできます。その有効期限を過ぎると、ピン留めが無効になります。 これにより、アップデートされていないアプリの接続の問題を防ぐことができます。 ただし、ピン留めに有効期限を設定すると、ピン留めを回避できるようになります。
res/xml/network_security_config.xml
:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config> <domain includeSubdomains="true">example.com</domain> <pin-set expiration="2018-01-01"> <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin> <!-- backup pin --> <pin digest="SHA-256">fwza0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM1oE=</pin> </pin-set> </domain-config> </network-security-config>
固有の構成で設定されていない値は、継承されます。この動作により、より複雑な構成が可能になるうえ、構成ファイルの読みやすさを維持できます。
固有のエントリに値が設定されていない場合、その次に汎用的なエントリの値が使用されます。 {@code domain-config} で設定されていない値は、ネストされている場合は親の {@code domain-config} から、ネストされていない場合は {@code base-config} から取得されます。 {@code base-config} で設定されていない値には、プラットフォームの既定値を使用します。
たとえば、{@code example.com} のサブドメインに対するすべての接続で、CA のカスタム セットを使用する必要があるケースを考えてみましょう。また、これらのドメインに対するクリアテキストのトラフィックは、{@code secure.example.com} に接続する場合を除いて許可します。 {@code example.com} の構成で {@code secure.example.com} の構成をネストすることで、 {@code trust-anchors} の重複を回避できます。
res/xml/network_security_config.xml
:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config> <domain includeSubdomains="true">example.com</domain> <trust-anchors> <certificates src="@raw/my_ca"/> </trust-anchors> <domain-config cleartextTrafficPermitted="false"> <domain includeSubdomains="true">secure.example.com</domain> </domain-config> </domain-config> </network-security-config>
ネットワーク セキュリティ構成機能では、XML ファイル形式を使用します。 ファイルの全体的な構造については、次のコード サンプルをご覧ください。
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config> <trust-anchors> <certificates src="..."/> ... </trust-anchors> </base-config> <domain-config> <domain>android.com</domain> ... <trust-anchors> <certificates src="..."/> ... </trust-anchors> <pin-set> <pin digest="...">...</pin> ... </pin-set> </domain-config> ... <debug-overrides> <trust-anchors> <certificates src="..."/> ... </trust-anchors> </debug-overrides> </network-security-config>
次のセクションでは、このファイル形式の構文とその他の詳細について説明します。
<base-config>
<domain-config>
<debug-overrides>
<base-config usesCleartextTraffic=["true" | "false"]> ... </base-config>
<trust-anchors>
domain-config
に含まれていない接続先に対するすべての接続に使用される、デフォルトの構成。
設定されていない値はすべて、プラットフォームの既定値を使用します。API レベル 24 以上をターゲットにしたアプリのデフォルトの構成は次のとおりです。
<base-config usesCleartextTraffic="true"> <trust-anchors> <certificates src="system" /> </trust-anchors> </base-config>API レベル 23 以下をターゲットにしたアプリのデフォルトの構成は次のとおりです。
<base-config usesCleartextTraffic="true"> <trust-anchors> <certificates src="system" /> <certificates src="user" /> </trust-anchors> </base-config>
<domain-config usesCleartextTraffic=["true" | "false"]> ... </domain-config>
<domain>
<trust-anchors>
<pin-set>
<domain-config>
複数の {@code domain-config} 要素で接続先を指定している場合は、最も具体的な(長い)マッチング ドメイン ルールを持つ構成が採用されます。
<domain includeSubdomains=["true" | "false"]>example.com</domain>
<debug-overrides> ... </debug-overrides>
<trust-anchors>
<trust-anchors> ... </trust-anchors>
<certificates>
<certificates src=["system" | "user" | "raw resource"] overridePins=["true" | "false"] />
ソースから取得した CA が証明書のピン留めを回避するかどうかを指定します。{@code "true"} の場合、証明書チェーンはこのソースから取得したいずれかの CA を使用して作成され、ピン留めは実行されません。 この設定は、CA をデバッグしたり、アプリのセキュアなトラフィックでユーザーの MiTM の許可をサポートするために役立ちます。
デフォルトは {@code "false"} です。ただし、{@code debug-overrides} 要素で指定された場合の既定値は {@code "true"} です。
<pin-set expiration="date"> ... </pin-set>
<pin>
<pin>
をご覧ください。
有効期限を設定しておくと、ユーザーがアプリのアップデートを無効にしているなどの原因で、ピンのセットのアップデートを取得していないアプリで、アプリの接続上の問題を回避できます。
<pin digest=["SHA-256"]>base64 encoded digest of X.509 SubjectPublicKeyInfo (SPKI)</pin>