La función Configuración de seguridad de red les permite a las apps personalizar opciones de seguridad de red mediante un archivo de configuración declarativo y seguro, sin necesidad de modificar el código de estas. Estas opciones se pueden configurar para dominios específicos y para una app específica. Las funciones clave son las siguientes:
- Anclajes de veracidad personalizados: Personaliza qué autoridades de certificación (CA) son de confianza para las conexiones de seguridad de una app. Por ejemplo, confiar en certificados autofirmados particulares o restringir el conjunto de CA públicas en las que confía la app.
- Anulaciones exclusivas de depuración: Depura de forma segura conexiones de una app sin riesgos adicionales para la base instalada.
- Inhabilitación de tráfico de Cleartext: Protege las apps contra el uso accidental del tráfico de Cleartext.
- Fijación de certificados: Restringe la conexión segura de una app con certificados específicos.
Cómo agregar un archivo de configuración de seguridad de red
La función de configuración de seguridad de red usa un archivo XML en el que se especifica la configuración de tu app. Debes incluir una entrada en el manifiesto de tu app para que apunte a este archivo. En el siguiente fragmento de código de un manifiesto, se muestra cómo crear esta entrada:
<?xml version="1.0" encoding="utf-8"?> <manifest ... > <application android:networkSecurityConfig="@xml/network_security_config" ... > ... </application> </manifest>
Cómo personalizar las CA de confianza
Es posible que una app quiera confiar en 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:
- Conectarse a un host con una autoridad de certificación personalizada, como una CA autofirmada o emitida a nivel interno en una empresa
- Limitar el conjunto de CA para que incluya solo aquellas en las que confías, en lugar de todas las que estén preinstaladas
- Otorgar confianza a CA adicionales que no estén incluidas en el sistema
De forma predeterminada, las conexiones seguras (con protocolos como TLS y HTTPS) de todas las apps confían en las CA preinstaladas del sistema, y las apps orientadas a Android 6.0 (API nivel 23) y versiones anteriores también confían, de forma predeterminada, en las CA que agrega el usuario. Una app puede personalizar sus propias conexiones mediante base-config
(para la personalización de toda la app) o domain-config
(para la personalización por dominio).
Cómo configurar una CA personalizada
Supongamos que quieres conectarte a tu host, que usa un certificado SSL autofirmado, o a un host cuyo certificado SSL está emitido por una CA privada en la que confías, como la 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 res/raw/my_ca
.
Cómo limitar el conjunto de CA de confianza
Una app que no quiera confiar en todas las CA que admita el sistema, de forma alternativa, especificar su propio conjunto reducido de CA en las que confiará. Esto brinda protección a la app ante 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 excepción de que se proporcionan varias 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 res/raw/trusted_roots
.
Ten en cuenta que, si usas el formato PEM, en el archivo se deben incluir solo datos PEM, sin texto adicional. También puedes proporcionar varios elementos <certificates>
en lugar de solo uno.
Cómo confiar en CA adicionales
Una app podría querer admitir CA adicionales en las que el sistema no confía, ya sea porque este aún no incluye la CA o porque la CA no cumple con los requisitos de inclusión del sistema Android. La app puede hacerlo especificando varias 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>
Cómo configurar las CA para depuración
Cuando depures una app que se conecte mediante HTTPS, recomendamos que te conectes a un servidor de desarrollo local que no tenga el certificado SSL de tu servidor de producción. Para poder hacerlo sin tener que modificar el código de tu app, puedes especificar CA de solo depuración a las cuales se les otorgue confianza únicamente cuando android:debuggable sea true
, con debug-overrides
. Generalmente, las herramientas de IDE y de compilación configuran este indicador automáticamente para las compilaciones no comerciales.
Esto es más seguro que el código condicional habitual ya que, como precaución, las tiendas de aplicaciones no aceptan apps 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>
Cómo desactivar el tráfico de Cleartext
Nota: Las instrucciones que se brindan en esta sección solo se aplican a las apps orientadas a Android 8.1 (nivel de API 27) o versiones anteriores. A partir de Android 9 (nivel de API 28), la compatibilidad de Cleartext está inhabilitada de forma predeterminada.
Las aplicaciones que intenten conectarse a destinos usando solo conexiones seguras pueden desactivar la compatibilidad con Cleartext (usando el protocolo HTTP sin encriptar en lugar del protocolo HTTPS) para esos destinos. Esta opción ayuda a prevenir las regresiones accidentales en apps debido a cambios en direcciones URL generados por fuentes externas como servidores backend.
Consulta NetworkSecurityPolicy.isCleartextTrafficPermitted()
para obtener más información.
Por ejemplo, es posible que una app busque garantizar que todas las conexiones a secure.example.com
se realicen siempre mediante HTTPS para proteger el tráfico sensible contra redes hostiles.
res/xml/network_security_config.xml
:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="false"> <domain includeSubdomains="true">secure.example.com</domain> </domain-config> </network-security-config>
Cómo fijar certificados
Generalmente, una app confía en todas las CA preinstaladas. Si alguna de estas emitiera un certificado fraudulento, la app podría sufrir el ataque de un intermediario. Algunas apps eligen limitar el conjunto de certificados que aceptan, ya sea mediante la limitación del conjunto de CA en el que confían o la fijación de certificados.
La fijación de certificados se realiza proporcionando 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 si usas la fijación de certificados, deberás incluir una clave de respaldo para que, si te ves obligado a usar claves nuevas o a cambiar de CA (al fijar un certificado de CA o un intermediario de ella), no se vea afectada la conectividad de la app. De lo contrario, deberás actualizar la app para recuperar la conectividad.
Además, se puede configurar un período de vencimiento para las fijaciones, luego del cual se detendrán los procesos correspondientes. Esto ayuda a evitar los problemas de conectividad en apps que no se hayan actualizado. Sin embargo, configurar un período de vencimiento para las fijaciones puede habilitar la omisión de estas.
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>
Comportamiento de la configuración heredada
Se heredarán los valores que no se establezcan en una configuración específica. Este comportamiento permite configuraciones más complejas y, al mismo tiempo, conserva la legibilidad del archivo de configuración.
Si no se especifica un valor en una entrada determinada, se usará el de la entrada más general. Por ejemplo, los valores que no se establecen en un elemento domain-config
se obtienen del elemento domain-config
principal si están anidados o del elemento base-config
si no lo están. Los valores no establecidos en base-config
usan los valores predeterminados de la plataforma.
Por ejemplo, considera los casos en que todas las conexiones a subdominios de example.com
deben usar un conjunto personalizado de CA. Además, el tráfico de Cleartext a estos dominios se permite, salvo durante la conexión a secure.example.com
.
Al anidar la configuración para secure.example.com
dentro de la configuración para example.com
, 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>
Formato del archivo de configuración
La función Configuración de seguridad de 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.
<network-security-config>
- puede contener:
-
0 o 1 de
<base-config>
Cualquier cantidad de<domain-config>
0 o 1 de<debug-overrides>
<base-config>
- sintaxis:
<base-config cleartextTrafficPermitted=["true" | "false"]> ... </base-config>
- puede contener:
-
<trust-anchors>
- Descripción:
- Es la configuración predeterminada que usan todas las conexiones cuyo destino no está abarcado por un elemento
domain-config
.Los valores que no están configurados usan los valores predeterminados de la plataforma.
La configuración predeterminada de las apps orientadas a Android 9 (nivel de API 28) y versiones posteriores es la siguiente:
<base-config cleartextTrafficPermitted="false"> <trust-anchors> <certificates src="system" /> </trust-anchors> </base-config>
La configuración predeterminada de las apps orientadas a Android 7.0 (nivel de API 24) hasta Android 8.1 (nivel de API 27) es la siguiente:
<base-config cleartextTrafficPermitted="true"> <trust-anchors> <certificates src="system" /> </trust-anchors> </base-config>
La configuración predeterminada de las apps orientadas a Android 6.0 (nivel de API 23) y versiones anteriores es la siguiente:
<base-config cleartextTrafficPermitted="true"> <trust-anchors> <certificates src="system" /> <certificates src="user" /> </trust-anchors> </base-config>
<domain-config>
- sintaxis:
-
<domain-config cleartextTrafficPermitted=["true" | "false"]> ... </domain-config>
- Puede contener:
-
1 o más
<domain>
0 o 1<trust-anchors>
0 o 1<pin-set>
Cualquier cantidad de elementos anidados<domain-config>
- Descripción
- Configuración usada para conexiones con destinos específicos, como los definidos por elementos
domain
.Ten en cuenta que, si varios elementos
domain-config
cubren un destino, se usará la configuración con la regla de coincidencia de dominio más específica (más larga).
<domain>
- sintaxis:
-
<domain includeSubdomains=["true" | "false"]>example.com</domain>
- Atributos:
-
-
includeSubdomains
- Si es
"true"
, esta regla de dominio coincide con el dominio y con todos los subdominios, incluidos los de subdominios. De lo contrario, solo se aplicará la regla a coincidencias exactas.
-
- Descripción:
<debug-overrides>
- sintaxis:
-
<debug-overrides> ... </debug-overrides>
- Puede contener:
-
0 o 1
<trust-anchors>
- Descripción:
- Anulaciones que se deben aplicar cuando android:debuggable es
"true"
, lo cual generalmente se atribuye a las compilaciones no comerciales generadas por herramientas de IDE y de compilación. Los anclajes de confianza especificados endebug-overrides
se agregan a todas las demás configuraciones, y la fijación de certificados no se lleva a cabo cuando la cadena de certificados del servidor usa uno de estos anclajes de confianza de solo depuración. Si android:debuggable es"false"
, esta sección se omite por completo.
<trust-anchors>
- sintaxis:
-
<trust-anchors> ... </trust-anchors>
- Puede contener:
-
Cualquier cantidad de
<certificates>
- Descripción:
- Conjunto de anclajes de confianza para conexiones seguras.
<certificates>
- sintaxis:
<certificates src=["system" | "user" | "raw resource"] overridePins=["true" | "false"] />
- descripción:
- Conjunto de certificados X.509 para elementos
trust-anchors
. - atributos:
-
src
-
Fuente de los certificados de CA. Cada certificado puede ser:
- Un ID de recurso sin procesar que se dirija a un archivo que contenga certificados X.509. Los certificados deben estar codificados en formato DER o PEM. En el caso de certificados PEM, el archivo no debe contener datos adicionales que no sean PEM, como comentarios.
"system"
para los certificados de CA preinstalados del sistema."user"
para certificados de CA agregados por el usuario.
overridePins
-
Especifica si las CA de esta fuente omiten la fijación de certificados. Si es
"true"
, no se realiza la fijación en las cadenas de certificados firmadas por una de las CA de esa fuente. Esto puede ser útil para depurar CA o para realizar pruebas de ataques de intermediarios en el tráfico seguro de tu app.De forma predeterminada, es
"false"
a menos que se especifique en un elementodebug-overrides
, en cuyo caso el valor predeterminado es"true"
.
<pin-set>
- sintaxis:
-
<pin-set expiration="date"> ... </pin-set>
- Puede contener:
-
Cualquier cantidad de
<pin>
- Descripción:
-
Es un conjunto de fijaciones de claves públicas. Para que una conexión segura sea de confianza, una de las claves públicas de la cadena de confianza debe estar en el conjunto de fijaciones. Consulta
<pin>
para obtener información sobre el formato de las fijaciones. - Atributos:
-
-
expiration
- Es la fecha, en formato
yyyy-MM-dd
, en la que caducan las fijaciones, con lo cual se inhabilita la fijación. Si no se establece el atributo, las fijaciones no vencen.El vencimiento ayuda a evitar problemas de conectividad en apps que no reciben actualizaciones para el conjunto de fijaciones; por ejemplo, cuando el usuario inhabilita las actualizaciones.
-
<pin>
- sintaxis:
-
<pin digest=["SHA-256"]>base64 encoded digest of X.509 SubjectPublicKeyInfo (SPKI)</pin>
- Atributos:
-
-
digest
-
Es el algoritmo implícito que se usa para generar la fijación. Actualmente, solo se admite
"SHA-256"
.
-
Recursos adicionales
Para obtener más información sobre la configuración de seguridad de la red, consulta los siguientes recursos.