Skip to content

Most visited

Recently visited

navigation

Configuración de seguridad de la red

La configuración de seguridad de la red permite a las apps personalizar los ajustes de seguridad de la red mediante un archivo de configuración declarativo seguro, sin necesidad de modificar el código de estas. Estos ajustes se pueden configurar para dominios específicos y para una app específica. Las capacidades claves de esta función son las siguientes:

Adición de un archivo de configuración de seguridad

La función de configuración de seguridad de la red usa un archivo XML en el que se especifican los ajustes para la app. Debes incluir una entrada en el manifiesto de tu app que apunte a este archivo. En el siguiente fragmento de código de un manifiesto se demuestra la manera de crear esta entrada:

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

Personalización de CA de confianza

Es posible que una app intente otorgar confianza a un conjunto personalizado de CA en lugar de los ajustes predeterminados de la plataforma. Las razones más comunes son las siguientes:

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 (nivel de API 23) y versiones anteriores también otorgan confianza, de forma predeterminada, en las CA agregadas por el usuario. Una app puede personalizar sus propias conexiones usando base-config (para la personalización de toda la app) o domain-config (para la personalización por dominio).

Configuración de una CA personalizada

Supongamos que deseas conectarte a tu host, que usa un certificado SSL autofirmado, o a un host cuyo certificado SSL está emitido por una CA no pública en la que 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 res/raw/my_ca.

Limitación del conjunto de CA de confianza

Una app que aplique la medida de no otorgar confianza en todas las CA en las que confía el sistema puede, como 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 otorgar confianza a CA adicionales

Es posible que una app otorgue confianza a CA adicionales en las cuales el sistema no confíe, 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 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>

Configuración de las CA para depuración

Cuando depures una app que se conecte mediante HTTPS, te recomendamos conectarte a un servidor de desarrollo local que no tenga el certificado SSL para 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 otorgue confianza únicamente cuando android:debuggable sea true, usando 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 de seguridad las tiendas de apps no aceptan apps 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

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 regresiones accidentales en las apps debido a cambios en las direcciones URL generados por fuentes externas como servidores de 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>

Fijación de certificados

Generalmente, una app otorga confianza a todas las CA preinstaladas. Si alguna de estas CA emitiera un certificado fraudulento, la app estaría en riesgo de sufrir un ataque de un intermediario. Algunas apps 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 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 cuando uses la fijación de certificados, siempre debes incluir una clave de respaldo para que, si te ves obligado a aplicar un cambio a claves nuevas o a cambiar de CA (al fijar un certificado de CA o un intermediario de esa CA), la conectividad de la app no se vea afectada. De lo contrario, deberás actualizar la app para recuperar la conectividad.

Además, se puede configurar un plazo de caducidad para las fijaciones, luego del cual las fijaciones dejen de realizarse. Esto ayuda a evitar los problemas de conectividad en apps que no se hayan actualizado. Sin embargo, configurar un plazo de caducidad 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>

Comportamiento de la configuración heredada

Los valores que no se establecen en una configuración específica se heredan. Este comportamiento permite configuraciones más complejas y, al mismo tiempo, conservan la legibilidad del archivo de configuración.

Si no se especifica un valor en una entrada determinada, se usa el valor de la entrada más general. Por ejemplo, los valores que no se establecen en una domain-config se obtienen de la domain-config principal, si están anidados, o de base-config si no lo están. Los valores no establecidos en la 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 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>

En las secciones siguientes describen la sintaxis y otros detalles del formato de archivo.

<network-security-config>

puede contener:
0 ó 1 <base-config>;
Cualquier cantidad de <domain-config>;
0 ó 1 <debug-overrides>.

<base-config>

sintaxis:
<base-config cleartextTrafficPermitted=["true" | "false"]>
    ...
</base-config>
puede contener:
<trust-anchors>
descripción:
Configuración predeterminada que usan todas las conexiones cuyo destino no está abarcado por una domain-config.

Los valores que no están configurados usan los valores predeterminados de la plataforma. La configuración predeterminada para las apps orientadas a Android 7.0 (nivel de API 24) y versiones posteriores es la siguiente:

<base-config cleartextTrafficPermitted="true">
    <trust-anchors>
        <certificates src="system" />
    </trust-anchors>
</base-config>
La configuración predeterminada para las apps orientadas a Android 6.0 (nivel de API 23) y versiones posteriores 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 ó 1 <pin-set>.
Cualquier cantidad de <domain-config> anidadas.
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 abarcan un destino, se usa la configuración con la regla de coincidencia de dominio más específica (más extensa).

<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, la regla solo se aplica a coincidencias exactas.
Descripción:

<debug-overrides>

sintaxis:
<debug-overrides>
    ...
</debug-overrides>
Puede contener:
0 ó 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 en debug-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 apunta a un archivo que contiene certificados X.509. Los certificados deben estar codificados en formato DER o PEM. En el caso de los 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 elemento debug-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:
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
Fecha, en formato yyyy-MM-dd, en la que caducan las fijaciones, con lo cual se inhabilita la fijación. Si el atributo no está establecido, las fijaciones no caducan.

La caducidad 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 de la app.

<pin>

sintaxis:
<pin digest=["SHA-256"]>base64 encoded digest of X.509
    SubjectPublicKeyInfo (SPKI)</pin>
Atributos:
digest
Algoritmo implícito usado para generar la fijación. Actualmente, solo se admite "SHA-256".
This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Follow Google Developers on WeChat

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience.
(Sep 2017 survey)