| page.title=Network Security Config |
| @jd:body |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| |
| <h2>In this document</h2> |
| <ol> |
| <li><a href="#SupportedFeatures">Features</a></li> |
| <li><a href="#Examples">Examples</a> |
| <ol> |
| <li><a href="#TrustingCustomCas">Trusting Custom CAs</a> |
| <ol> |
| <li><a href="#TrustingACustomCa">Trusting a Custom CA</a></li> |
| <li><a href="#LimitingCas">Limiting the Set of Trusted CAs</a></li> |
| <li><a href="#TrustingAdditionalCas">Trusting Additional CAs</a></li> |
| </ol> |
| </li> |
| <li><a href="#TrustingDebugCa">Debugging-only CAs</a></li> |
| <li><a href="#UsesCleartextTraffic">Cleartext Traffic Opt-Out</a></li> |
| <li><a href="#CertificatePinning">Certificate Pinning</a></li> |
| <li><a href="#ConfigInheritance">Configuration Inheritance</a></li> |
| </ol> |
| </li> |
| <li><a href="#FileFormat">Configuration File Format</a></li> |
| </ol> |
| </div> |
| </div> |
| |
| <p>The Android Network Security Config lets apps customize their network security settings |
| in a safe, declarative configuration file without modifying application code. |
| These settings can be configured for specific domains and app-wide.</p> |
| |
| <h2 id="SupportedFeatures">Features</h2> |
| <ul> |
| <li><b>Custom trust anchors.</b> Lets an application customize which Certificate Authorities (CA) are trusted |
| for its secure connections. For example, trusting particular self-signed certificates or restricting the set of public |
| CAs that the app trusts. |
| </li> |
| <li><b>Debug-only overrides.</b> Lets an application developer safely debug secure connections of their |
| application without added risk to the installed base. |
| </li> |
| <li><b>Cleartext traffic opt-out.</b> Lets an application protect itself from accidental usage of cleartext traffic.</li> |
| <li><b>Certificate pinning.</b> An advanced feature that lets an application restrict pin its secure connection |
| to particular certificates.</li> |
| </ul> |
| |
| <h2 id="Examples">Examples</h2> |
| <h3 id="TrustingCustomCas">Trusting Custom CAs</h3> |
| <p>An application may want to trust a custom set of CAs instead of the platform |
| default. The most common reasons of this are: |
| <ul> |
| <li>Connecting to a host with a custom certificate authority(self-signed, issued by an internal corporate CA, etc).</li> |
| <li>Limiting the set of CAs to only the CAs you trust instead of every preinstalled CA.</li> |
| <li>Trusting additional CAs not included in the system.</li> |
| </ul> |
| </p> |
| <p>By default secure (e.g. TLS, HTTPS) connections from all applications trust the pre-installed system CAs, and |
| applications targeting API level 23 (Android M) and below also trust the user-added CA store by default. |
| An application can customize its own connections using {@code base-config} (for app-wide customization) or |
| {@code domain-config} (for per-domain customization).</p> |
| |
| <h4 id="TrustingACustomCa">Trusting a Custom CA</h4> |
| <p>Assume you want to connect to your host which uses a self-signed SSL certificate or to |
| a host whose SSL certificate is issued by a non-public CA which you trust, e.g., your company's internal |
| CA.</p> |
| <p> |
| <code>res/xml/network_security_config.xml</code>: |
| <pre> |
| <?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> |
| </pre> |
| </p> |
| <p>Add the self-signed or non-public CA certificate, in PEM or DER format, to {@code res/raw/my_ca}.</p> |
| <p> |
| In <code>AndroidManifest.xml</code> reference the above config |
| <pre> |
| <?xml version="1.0" encoding="utf-8"?> |
| ... |
| <application ...> |
| <meta-data android:name="android.security.net.config" |
| android:resource="@xml/network_security_config" /> |
| ... |
| </pre> |
| </p> |
| <h4 id="LimitingCas">Limiting the Set of Trusted CAs</h4> |
| <p>An application that does not want to trust all CAs trusted by system can instead specify its own |
| reduced set of CAs to trust. This protects the application from fradulent certificates issued by any |
| of the other CAs.</p> |
| |
| <p>The config to limit the set of trusted CAs is similar to <a href="#TrustingACustomCa">trusting a custom CA</a> |
| for a specific domain except that multiple CAs are provided in the resource.</p> |
| |
| <p> |
| <code>res/xml/network_security_config.xml</code>: |
| <pre> |
| <?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> |
| </pre> |
| </p> |
| <p>Add the trusted CAs, in PEM or DER format, to {@code res/raw/trusted_roots}. |
| Note that if using PEM format the file must contain <em>only</em> PEM data and no extra text. |
| You can also provide multiple <a href="certificates"><code><certificates></code></a> elements instead |
| of one.</p> |
| <p> |
| In <code>AndroidManifest.xml</code> reference the above config |
| <pre> |
| <?xml version="1.0" encoding="utf-8"?> |
| ... |
| <application ...> |
| <meta-data android:name="android.security.net.config" |
| android:resource="@xml/network_security_config" /> |
| ... |
| </pre> |
| </p> |
| |
| <h4 id="TrustingAdditionalCas">Trusting Additional CAs</h4> |
| <p>An application may want to trust additional CAs not trusted by the system, this could be due to |
| the system not yet including the CA or a CA that does not meet the requirements for inclusion into |
| the Android system. An application can do this by specifying multiple certificate sources for a configuration. |
| </p> |
| <p> |
| <code>res/xml/network_security_config.xml</code>: |
| <pre> |
| <?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> |
| </pre> |
| </p> |
| <p> |
| In <code>AndroidManifest.xml</code> reference the above config |
| <pre> |
| <?xml version="1.0" encoding="utf-8"?> |
| ... |
| <application ...> |
| <meta-data android:name="android.security.net.config" |
| android:resource="@xml/network_security_config" /> |
| ... |
| </pre> |
| </p> |
| |
| <h3 id="TrustingDebugCa">Debugging-only CAs</h3> |
| <p>When debugging an application that connects over HTTPS you may want to connect to a local development |
| server, which does not have the SSL certificate for your production server. In order to support this |
| without any modification to your application's code you can specify debug-only CAs that are |
| <i>only</i> trusted when <a href="{@docRoot}guide/topics/manifest/application-element.html#debug">android:debuggable</a> |
| is {@code true} by using {@code debug-overrides}. Normally IDEs and build tools set this flag automatically for non-release builds.</p> |
| <p>This is safer than the usual conditional code because, as a security precaution, application stores |
| do not accept applications which are marked debuggable.</p> |
| |
| <p> |
| <code>res/xml/network_security_config.xml</code>: |
| <pre> |
| <?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> |
| </pre> |
| </p> |
| <p> |
| In <code>AndroidManifest.xml</code> reference the above config |
| <pre> |
| <?xml version="1.0" encoding="utf-8"?> |
| ... |
| <application ...> |
| <meta-data android:name="android.security.net.config" |
| android:resource="@xml/network_security_config" /> |
| ... |
| </pre> |
| </p> |
| |
| <h3 id="UsesCleartextTraffic">Cleartext Traffic Opt-Out</h3> |
| <p>Applications which intend to connect to destinations using only secure connections can opt-out |
| of supporting cleartext (i.e. plain HTTP instead of HTTPS) to those destinations. This helps prevent |
| accidental regressions in applications due to changes in URLs provided by external sources such as |
| backend servers.</p> |
| <p>See {a href="{@docRoot}reference/android/security/NetworkSecurityPolicy.html#isCleartextTrafficPermitted()} for more details.</p> |
| |
| <p>For example, an application may want to ensure that all connections to {@code secure.example.com} are always |
| done over HTTPS to protect sensitive traffic from hostile networks.</p> |
| |
| <p> |
| <code>res/xml/network_security_config.xml</code>: |
| <pre> |
| <?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> |
| </pre> |
| </p> |
| <p> |
| In <code>AndroidManifest.xml</code> reference the above config |
| <pre> |
| <?xml version="1.0" encoding="utf-8"?> |
| ... |
| <application ...> |
| <meta-data android:name="android.security.net.config" |
| android:resource="@xml/network_security_config" /> |
| ... |
| </pre> |
| </p> |
| |
| <h3 id="CertificatePinning">Certificate Pinning</h3> |
| <p>Normally an application trusts all preinstalled CAs. If any of these CAs were to issue a fradulent certificate |
| the application would be at risk from a MiTM attack. Some applications choose to limit the set of |
| certificates they accept by either limiting the set of CAs they trust or by certificate pinning.</p> |
| |
| <p>Certificate pinning is done by providing a set of certificates by hash of the public key (SubjectPublicKeyInfo |
| of the X.509 certificate). A certificate chain is then only valid if the certificate chain contains at least |
| one of the pinned public keys.</p> |
| |
| <p>Note that when using certificate pinning you should always include a backup key so that if you |
| are forced to switch to new keys, or change CAs (when pinning to a CA certificate or an intermediate of that CA), |
| your application's connectivity is unaffected. Otherwise you will have to push out an update to the |
| application to restore connectivity.</p> |
| |
| <p>Additionally it is possible to set an expiration time for pins after which pinning will not be |
| performed. This helps prevent connectivity issues in applications which have not been updated. |
| However, setting an expiration time on pins may enable pinning bypass. |
| </p> |
| |
| <p> |
| <code>res/xml/network_security_config.xml</code>: |
| <pre> |
| <?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> |
| </domain-config> |
| </network-security-config> |
| </pre> |
| </p> |
| <p> |
| In <code>AndroidManifest.xml</code> reference the above config |
| <pre> |
| <?xml version="1.0" encoding="utf-8"?> |
| ... |
| <application ...> |
| <meta-data android:name="android.security.net.config" |
| android:resource="@xml/network_security_config" /> |
| ... |
| </pre> |
| </p> |
| |
| <h3 id="ConfigInheritance">Configuration Inheritance</h3> |
| <p>Values not set in a specific config will be inherited. |
| This allows more complex configurations while keeping the configuration file readable.</p> |
| |
| <p>If a value is not set in a specific entry then value from the next more general entry will be used. |
| Values not set in a {@code domain-config} will be taken from the parent {@code domain-config}, if nested, or |
| from the {@code base-config} if not. Values not set in the {@code base-config} will use |
| the platform default values. |
| |
| <p>For example consider, where all connections to subdomains of {@code example.com} |
| must use a custom set of CAs. Additonally cleartext traffic to these domains is permitted |
| <em>except</em> when connecting to {@code secure.example.com}. By nesting the configuration |
| for {@code secure.example.com} inside the configuration for {@code example.com} the |
| {@code trust-anchors} does not need to be duplicated.</p> |
| |
| <p> |
| <code>res/xml/network_security_config.xml</code>: |
| <pre> |
| <?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> |
| </pre> |
| </p> |
| <p> |
| In <code>AndroidManifest.xml</code> reference the above config |
| <pre> |
| <?xml version="1.0" encoding="utf-8"?> |
| ... |
| <application ...> |
| <meta-data android:name="android.security.net.config" |
| android:resource="@xml/network_security_config" /> |
| ... |
| </pre> |
| </p> |
| |
| <h2 id="FileFormat">Configuration File Format</h2> |
| <p>The configuration file is XML. Here is what it can contain:</p> |
| </p> |
| <pre> |
| <?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> |
| </pre> |
| |
| <h3 id="network-security-config"><network-security-config></h3> |
| <dl class="xml"> |
| <dt>can contain:</dt> |
| <dd>0 or 1 <code><a href="#base-config"><base-config></a></code> |
| <br/>Any number of <code><a href="#domain-config"><domain-config></a></code> |
| <br/>0 or 1<code><a href="#debug-overrides"><debug-overrides></a></code> |
| </dd> |
| </dl> |
| |
| |
| <h3 id="base-config"><base-config></h3> |
| <dl class="xml"> |
| <dt>syntax:</dt> |
| <dd><pre class="stx"><base-config <a href="#usesCleartextTraffic">usesCleartextTraffic</a>=["true" | "false"]> |
| ... |
| </base-config></pre></dd> |
| <dt>can contain:</dt> |
| <dd><code><a href="#trust-anchors"><trust-anchors></a></code></dd> |
| <dt>descrption:</dt> |
| <dd> |
| The default configuration used by all connections whose destination is not covered by a |
| <a href="#domain-config"><code>domain-config</code></a>. |
| |
| <p>Any values that are not set will use the platform default values. |
| The default configuration for applications targeting above API level 24 and above: |
| <pre> |
| <base-config usesCleartextTraffic="true"> |
| <trust-anchors> |
| <certificates src="system" /> |
| </trust-anchors> |
| </base-config> |
| </pre> |
| The default configuration for applications targeting API level 23 and below is: |
| <pre> |
| <base-config usesCleartextTraffic="true"> |
| <trust-anchors> |
| <certificates src="system" /> |
| <certificates src="user" /> |
| </trust-anchors> |
| </base-config> |
| </pre> |
| </p> |
| </dd> |
| </dl> |
| |
| <h3 id="domain-config"><domain-config></h3> |
| <dl class="xml"> |
| <dt>syntax:</dt> |
| <dd><pre class="stx"><domain-config <a href="#usesCleartextTraffic">usesCleartextTraffic</a>=["true" | "false"]> |
| ... |
| </domain-config></pre></dd> |
| <dt>Can Contain:</dt> |
| |
| <dd> |
| 1 or more <code><a href="#domain"><domain></a></code> |
| <br/>0 or 1 <code><a href="#trust-anchors"><trust-anchors></a></code> |
| <br/>0 or 1 <code><a href="#pin-set"><pin-set></code></a> |
| <br/>Any number of nested <code><domain-config></code></dd> |
| |
| <dt>Descrption</dt> |
| <dd>Configuration used for connections to specific destinations as the defined by {@code domain} elements. |
| |
| <p>Note that if multiple {@code domain-config} elements cover a destination the config with the most specific (longest) |
| matching domain rule will be used.</p></dd> |
| </dl> |
| |
| <h3 id="domain"><domain></h3> |
| <dl class="xml"> |
| <dt>syntax:</dt> |
| <dd><pre class="stx"><domain includeSubdomains=["true" | "false"]>example.com</domain></pre></dd> |
| <dt>Attributes:</dt> |
| <dd><dl class="attr"> |
| <dt>{@code includeSubdomains}</dt> |
| <dd>If {@code "true"} then this domain rule will match the domain and all subdomains, including |
| subdomains of subdomains, otherwise the rule only applies to exact matches.</dd> |
| </dl> |
| </dd> |
| |
| <dt>Descrption:</dt> |
| </dl> |
| |
| <h3 id="debug-overrides"><debug-overrides></h3> |
| <dl class="xml"> |
| <dt>syntax:</dt> |
| <dd><pre class="stx"><debug-overrides> |
| ... |
| </debug-overrides></pre></dd> |
| <dt>Can Contain:</dt> |
| <dd>0 or 1 <code><a href="#trust-anchors"><trust-anchors></a></code></dd> |
| <dt>Description:</dt> |
| <dd>Overrides to be applied when |
| <a href="{@docRoot}guide/topics/manifest/application-element.html#debug">android:debuggable</a> is |
| {@code "true"} which is normally the case for non-release builds generated by IDEs and build tools. |
| Trust anchors specified in {@code debug-overrides} are added to all other configurations and certificate |
| pinning is not performed when the server's certificate chain uses one of these debug-only trust anchors. |
| If <a href="{@docRoot}guide/topics/manifest/application-element.html#debug">android:debuggable</a> is |
| {@code "false"} then this section is completely ignored. |
| </dd> |
| </dl> |
| |
| <h3 id="trust-anchors"><trust-anchors></h3> |
| <dl class="xml"> |
| <dt>syntax:</dt> |
| <dd> |
| <pre class="stx"><trust-anchors> |
| ... |
| </trust-anchors> |
| </pre></dd> |
| <dt>Can Contain:</dt> |
| <dd>Any number of <code><a href="#certificates"><certificates></a></code></dd> |
| <dt>Description:</dt> |
| <dd>Set of trust anchors for secure connections.</dd> |
| </dl> |
| |
| |
| <h3 id="certificates"><certificates></h3> |
| <dl class="xml"> |
| <dt>syntax:</dt> |
| <dd><pre class="stx"><certificates src=["system" | "user" | "<i>raw resource</i>"] |
| overridePins=["true" | "false"] /> |
| </pre></dd> |
| <dt>description:</dt> |
| <dd>Set of X.509 certificates for {@code trust-anchors} elements.</dd> |
| |
| <dt>attributes:</dt> |
| <dd><dl class="attr"> |
| <dt>{@code src}</dt> |
| <dd> |
| The source of CA certificates, can be one of |
| <ul> |
| <li>a raw resource id pointing to a file containing X.509 certificates. Certificates must be encoded in DER or PEM format. |
| In the case of PEM certificates the file <em>must not</em> contain extra non-PEM data such as comments.</li> |
| <li>{@code "system"} for the pre-installed system CA certificates</li> |
| <li>{@code "user"} for user-added CA certificates</li> |
| </ul> |
| </dd> |
| |
| <dt>{@code overridePins}</dt> |
| <dd> |
| Specifies if the CAs from this source bypass certificate pinning. If {@code "true"} then certificate chains which |
| chain through one of the CAs from this source then pinning will not be performed. This can be useful |
| for debug CAs or to support letting the user MiTM your app's secure traffic. |
| <p> |
| Default is {@code "false"} unless specified in a {@code debug-overrides} element, in which case the default is {@code "true"}. |
| </p> |
| </dd> |
| </dl> |
| </dd> |
| |
| <h3 id="pin-set"><pin-set></h3> |
| <dl class="xml"> |
| <dt>syntax:</dt> |
| <dd> |
| <pre class="stx"><pin-set expiration="date"> |
| ... |
| </pin-set> |
| </pre></dd> |
| <dt>Can Contain:</dt> |
| <dd>Any number of <code><a href="#pin"><pin></a></code></dd> |
| <dt>Description:</dt> |
| <dd>A set of public key pins. For a secure connection to be trusted, one of the public keys in the chain of trust must |
| be in the set of pins. See <code><a href="#pin"><pin></a></code> for the format of pins.</dd> |
| <dt>Attributes:</dt> |
| <dd><dl class="attr"> |
| <dt>{@code expiration}</dt> |
| <dd>The date, in {@code yyyy-MM-dd} format, at and after which the pins expire, thus disabling pinning. |
| If the attribute is not set then the pins do not expire. |
| <p>Expiration helps prevent connectivity issues in applications which do not get updates to their |
| pin set, for example because the user disabled application updates.</p> |
| </dd> |
| </dl> |
| </dd> |
| |
| <h3 id="pin"><pin></h3> |
| <dl class="xml"> |
| <dt>syntax:</dt> |
| <dd> |
| <pre class="stx"><pin digest=["SHA-256"]>base64 encoded digest of X.509 SubjectPublicKeyInfo (SPKI)</pin></pre></dd> |
| <dt>Attributes:</dt> |
| <dd><dl class="attr"> |
| <dt>{@code digest}</dt> |
| <dd>The digest algorithm used to generate the pin. Currently only {@code "SHA-256"} is supported.</dd> |
| </dl> |
| </dd> |
| </dl> |