page.title=Configuración de seguridad de la red page.keywords=androidn,security,network page.image=images/cards/card-nyc_2x.jpg @jd:body
Android N incluye una función de configuración de seguridad de la red que les permite a las aplicaciones personalizar los ajustes de seguridad de la red mediante un archivo de configuración declarativo seguro sin que haya que modificar el código de la aplicación. Estos ajustes se pueden configurar para dominios específicos y para una aplicación específica. Las capacidades clave de esta función son las siguientes:
La función de configuración de seguridad de la red usa un archivo XML donde se especifican los ajustes para la aplicación. Debes incluir una entrada en el manifiesto de tu aplicación que apunte a este archivo. El siguiente fragmento de código de un manifiesto demuestra cómo crear esta entrada:
<?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>
Una aplicación podría querer otorgar confianza a un conjunto personalizado de CA en lugar de hacerlo según los ajustes predeterminados de la plataforma. Las razones más comunes son las siguientes:
De forma predeterminada, las conexiones seguras (p. ej.: TLS, HTTP) de todas las aplicaciones dependen de las CA preinstaladas del sistema; las aplicaciones que tienen como objetivo a la API nivel 23 (Android M) e inferiores también dependen de la tienda de CA agregada por el usuario de forma predeterminada. Una aplicación puede personalizar sus propias conexiones usando {@code base-config} (para la personalización de toda la aplicación) o {@code domain-config} (para la personalización por dominio).
Supongamos que deseas conectarte a tu host, el cual usa un certificado SSL autofirmado, o a un host cuyo certificado SSL está emitido por una CA no pública en la cual confías, como la CA interna de tu empresa.
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>
Agrega el certificado de CA autofirmado o no público, en formato PEM o DER, a {@code res/raw/my_ca}.
Una aplicación que no desee confiar en todas las CA en que confía el sistema puede, en su lugar, especificar su propio conjunto reducido de CA en las que confía. Esto protege a la aplicación de certificados fraudulentos emitidos por cualquiera de las demás CA.
La configuración para limitar el conjunto de CA de confianza es similar a confiar en una CA personalizada para un dominio específico, con la diferencia de que se brindan múltiples CA en el recurso.
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>
Agrega las CA de confianza, en formato PEM o DER, a {@code res/raw/trusted_roots}.
Ten en cuenta que, si usas el formato PEM, el archivo debe incluir solo datos PEM
y ningún texto adicional. También puedes brindar elementos
<certificates>
múltiples en lugar de solo uno.
Una aplicación podría querer otorgar confianza a CA adicionales en las cuales el sistema no confía, ya sea porque el sistema aún no incluye la CA o porque la CA no cumple con los requisitos de inclusión del sistema Android. La aplicación puede hacerlo especificando múltiples fuentes de certificado para una configuración.
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>
Cuando depuras una aplicación que se conecta mediante HTTPS, podrías querer conectarte a un servidor de desarrollo local que no tiene el certificado SSL de tu servidor de producción. Para poder hacerlo sin tener que modificar el código de tu aplicación, puedes especificar CA de solo depuración que solo son de confianza cuando android:debuggable es {@code true} usando {@code debug-overrides}. Generalmente, las herramientas de IDE y de compilación configuran esta marca automáticamente para las compilaciones que no son de lanzamiento.
Esto es más seguro que el código condicional habitual ya que, como precaución de seguridad, las tiendas de aplicaciones no aceptan aplicaciones que están marcadas como depurables.
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>
Las aplicaciones que deseen conectarse a destinos usando solo conexiones seguras pueden desactivar Cleartext (usando el protocolo HTTP no encriptado en lugar del protocolo HTTPS) para esos destinos. Esta opción ayuda a prevenir las regresiones accidentales en aplicaciones debido a cambios en direcciones URL generados por fuentes externas como servidores backend. Consulta {@link android.security.NetworkSecurityPolicy#isCleartextTrafficPermitted NetworkSecurityPolicy.isCleartextTrafficPermitted()} para obtener más información.
Por ejemplo, una aplicación puede querer garantizar que todas las conexiones a {@code secure.example.com} se hagan siempre mediante HTTPS para proteger el tráfico sensible de redes hostiles.
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>
Generalmente, una aplicación otorga confianza a todas las CA preinstaladas. Si alguna de estas CA emitiera un certificado fraudulento, la aplicación estaría en riesgo de sufrir un ataque MiTM. Algunas aplicaciones eligen limitar el conjunto de certificados que aceptan ya sea limitando el conjunto de CA al que otorgan confianza o fijando certificados.
La fijación de certificados se hace brindando un conjunto de certificados por hash de la clave pública (SubjectPublicKeyInfo del certificado X.509). De este modo, una cadena de certificados solo es válida si contiene al menos una de las claves públicas fijadas.
Ten en cuenta que, cuando uses la fijación de certificados, siempre debes incluir una clave de respaldo para que, si te ves obligado a cambiar a claves nuevas o a cambiar de CA (cuando fijas un certificado de CA o un intermediario de esa CA), la conectividad de la aplicación no se vea afectada. Si no, deberás actualizar la aplicación para recuperar la conectividad.
Además, se puede configurar un tiempo de expiración para las fijaciones, luego del cual las fijaciones dejan de realizarse. Esto ayuda a evitar los problemas de conectividad en aplicaciones que no se han actualizado. Sin embargo, configurar un tiempo de expiración para las fijaciones puede habilitar la omisión de fijaciones.
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>
Los valores que no se establecen en una configuración específica se heredan. Este comportamiento permite configuraciones más complejas y un archivo de configuración de fácil lectura.
Si no se establece un valor en una entrada específica, se usa el valor de la siguiente entrada más general. Los valores no establecidos en una {@code domain-config} se toman de la {@code domain-config} primaria, si están anidados, o de la {@code base-config}, si no están anidados. Los valores no establecidos en la {@code base-config} usan los valores predeterminados de la plataforma.
Por ejemplo, cuando todas las conexiones a subdominios de {@code example.com} deben usar un conjunto personalizado de CA. Además, el tráfico de Cleartext a estos dominios se permite excepto con las conexiones a {@code secure.example.com}. Anidando la configuración para {@code secure.example.com} dentro de la configuración para {@code example.com}, {@code trust-anchors} no necesita duplicación.
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>
La función de configuración de seguridad de la red usa un formato de archivo XML. La estructura general del archivo se muestra en el siguiente ejemplo de código:
<?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>
Las siguientes secciones describen la sintaxis y otros detalles del formato de archivo.
<base-config>
<domain-config>
<debug-overrides>
<base-config usesCleartextTraffic=["true" | "false"]> ... </base-config>
<trust-anchors>
domain-config
.
Los valores que no están configurados usan los valores predeterminados de la plataforma. La configuración predeterminada para aplicaciones con API nivel 24 o superior es:
<base-config usesCleartextTraffic="true"> <trust-anchors> <certificates src="system" /> </trust-anchors> </base-config>La configuración predeterminada para aplicaciones con API nivel 23 o inferior es:
<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>
anidadasTen en cuenta que, si múltiples elementos de {@code domain-config} cubren un destino, la configuración con la regla de coincidencia de dominio más específica (más larga) es la que se usa.
<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"] />
Especifica si las CA de esta fuente omiten la fijación de certificados. Si es {@code "true"}, las cadenas de certificados se encadenan mediante una de estas CA desde esta fuente, y la fijación no se lleva a cabo. Esto puede ser útil para CA de depuración o para poder permitirle al usuario hacer un ataque MiTM al tráfico seguro de la aplicación.
Es {@code "false"} de forma predeterminada, a menos que se especifique en un elemento de {@code debug-overrides} , en cuyo caso, es {@code "true"} de forma predeterminada.
<pin-set expiration="date"> ... </pin-set>
<pin>
<pin>
para el formato de las fijaciones.
La expiración ayuda a evitar problemas de conectividad en aplicaciones que no reciben actualizaciones para el conjunto de fijaciones, por ejemplo, porque el usuario deshabilitó las actualizaciones de la aplicación.
<pin digest=["SHA-256"]>base64 encoded digest of X.509 SubjectPublicKeyInfo (SPKI)</pin>