page.title=Configuração de segurança de rede page.keywords=androidn,security,network page.image=images/cards/card-nyc_2x.jpg @jd:body

Neste documento

  1. Adicionar um arquivo de configurações de segurança
  2. Personalizar CAs confiáveis
    1. Configurar uma CA personalizada confiável
    2. Limitar o conjunto de CAs confiáveis
    3. Confiar em CAs adicionais
  3. CAs somente de depuração
  4. Cancelar uso de tráfego de texto simples
  5. Fixar certificados
  6. Comportamento de herança de configuração
  7. Formato do arquivo de configurações

O Android N inclui um recurso de configurações de segurança de rede que permite que os aplicativos personalizem as configurações de segurança de rede em um arquivo de configurações declarativo e seguro sem modificar o código do aplicativo. Essas configurações podem ser definidas para domínios específicos e para um aplicativo específico. Os principais recursos são:

Adicionar um arquivo de configurações de segurança

O recurso de configurações de segurança de rede usa um arquivo XML no qual você especifica as configurações do seu aplicativo. Inclua uma entrada no manifesto do seu aplicativo para apontar para esse arquivo. Este trecho de código de um manifesto demonstra como criar essa 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>

Personalizar CAs confiáveis

Um aplicativo pode querer confiar em um conjunto personalizado de CAs em vez de no padrão da plataforma. Os motivos mais comuns para isso são:

Por padrão, conexões seguras (por exemplo, TLS, HTTPS) de todos os aplicativos confiam nas CAs pré-instaladas do sistema e os aplicativos direcionados ao nível da API 23 (Android M) e inferior também confiam no repositório de CAs adicionadas pelo usuário por padrão. Um aplicativo pode personalizar as próprias conexões usando {@code base-config} (para personalização em todo o aplicativo) ou {@code domain-config} (para personalização por domínio).

Configurar uma CA personalizada

Suponhamos que você queira se conectar a um host que use um certificado SSL autoassinado ou a um host cujo certificado SSL foi emitido por uma CA não pública na qual confia, como a CA interna da sua 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>

Adicione o certificado da CA autoassinada ou não pública em formato PEM ou DER em {@code res/raw/my_ca}.

Limitar o conjunto de CAs confiáveis

Um aplicativo que não queira confiar em todas as CAs nas quais o sistema confia pode especificar o próprio conjunto limitado de CAs confiáveis. Isso protege o aplicativo contra certificados fraudulentos emitidos por qualquer outra CA.

A configuração para limitar o conjunto de CAs confiáveis é semelhante a confiar em uma CA personalizada para um domínio específico, mas fornecendo várias CAs no 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>

Adicione as CAs confiáveis em formato PEM ou DER em {@code res/raw/trusted_roots}. Observe que, ao usar o formato PEM, o arquivo deve conter somente dados PEM, sem texto adicional. Você também pode fornecer vários elementos <certificates> em vez de um.

Confiar em CAs adicionais

Um aplicativo pode querer confiar em CAs adicionais nas quais o sistema não confia. Isso pode ocorrer se o sistema ainda não incluiu a CA ou se a CA não atender aos requisitos de inclusão no sistema Android. O aplicativo pode fazer isso ao especificar várias fontes de certificados para uma configuração.

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>

Configurar CAs para depuração

Ao depurar um aplicativo conectado por HTTPS, você pode querer se conectar a um servidor de desenvolvimento local que não tenha o certificado SSL do seu servidor de produção. Para fazer isso sem modificar o código do aplicativo, você pode especificar CAs somente de depuração que sejam confiáveis apenas quando android:debuggable for {@code true} ao usar {@code debug-overrides}. Normalmente, IDEs e ferramentas de compilação definem esse sinalizador automaticamente para compilações de não lançamento.

Isso é mais seguro do que o código condicional normal, pois, como medida de segurança, os repositórios do aplicativo não aceitam aplicativos marcados como depuráveis.

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>

Cancelar uso de tráfego de texto simples

Aplicativos que pretendem se conectar a destinos usando apenas conexões seguras podem cancelar o uso de texto simples de suporte (usando o protocolo HTTP não criptografado em vez de HTTPS) para esses destinos. Essa opção ajuda a evitar regressões acidentais em aplicativos devido a alterações nos URLs fornecidos por fontes externas, como servidores de back-end. Consulte {@link android.security.NetworkSecurityPolicy#isCleartextTrafficPermitted NetworkSecurityPolicy.isCleartextTrafficPermitted()} para saber mais.

Por exemplo, um aplicativo pode querer garantir que todas as conexões com {@code secure.example.com} sejam sempre realizadas por HTTPS para proteger o tráfego confidencial de redes hostis.

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>

Fixar certificados

Normalmente, um aplicativo confia em todas as CAs pré-instaladas. Se qualquer uma dessas CAs emitir um certificado fraudulento, o aplicativo estará em risco de ataques MiTM. Alguns aplicativos optam por limitar o conjunto de certificados que aceitam restringindo o conjunto de CAs ou fixando certificados.

A fixação de certificados é realizada ao fornecer um conjunto de certificados pelo hash da chave pública (SubjectPublicKeyInfo do certificado X.509). Uma cadeia de certificados é válida somente se contiver pelo menos uma das chaves públicas fixadas.

Observe que, ao usar a fixação de certificados, você deve sempre incluir uma chave de backup para que, se você for forçado a alternar para novas chaves ou alterar as CAs (ao fixar um certificado de CA ou um intermediário dessa CA), a conectividade do seu aplicativo não seja afetada. Caso contrário, você precisará enviar uma atualização ao aplicativo para restaurar a conectividade.

Além disso, é possível definir um tempo de expiração para as fixações, após o qual elas não sejam mais realizadas. Isso ajuda a evitar problemas de conectividade em aplicativos que não foram atualizados. No entanto, definir um tempo de expiração para fixações pode permitir que as fixações sejam ignoradas.

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>

Comportamento de herança de configuração

Valores não definidos em uma configuração específica são herdados. Esse comportamento permite configurações mais complexas, mantendo o arquivo de configuração legível.

Se um valor não for definido em uma entrada específica, o valor da próxima entrada mais genérica será usado. Valores não definidos em um {@code domain-config} são obtidos pelo {@code domain-config} pai, se aninhados, ou, caso contrário, pelo {@code base-config}. Valores não definidos no {@code base-config} usam os valores padrão da plataforma.

Por exemplo, considere um caso no qual todas as conexões para subdomínios de {@code example.com} devem usar um conjunto personalizado de CAs. Além disso, o tráfego de texto simples para esses domínios é permitido exceto ao se conectar com {@code secure.example.com}. Ao aninhar a configuração para {@code secure.example.com} dentro da configuração para {@code example.com}, o {@code trust-anchors} não precisa ser duplicado.

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 do arquivo de configurações

O recurso de configurações de segurança de rede usa um formato do arquivo XML. A estrutura geral desse arquivo é mostrada no seguinte exemplo 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>

As seções a seguir descrevem a sintaxe e outros detalhes do formato do arquivo.

<network-security-config>

pode conter:
0 ou 1 de <base-config>
Qualquer número de <domain-config>
0 ou 1 de <debug-overrides>

<base-config>

sintaxe:
<base-config usesCleartextTraffic=["true" | "false"]>
    ...
</base-config>
pode conter:
<trust-anchors>
descrição:
A configuração padrão usada por todas as conexões cujo destino não é coberto por um domain-config.

Qualquer valor não definido usa os valores padrão da plataforma. A configuração padrão para aplicativos direcionados a níveis de API acima do 24:

<base-config usesCleartextTraffic="true">
    <trust-anchors>
        <certificates src="system" />
    </trust-anchors>
</base-config>
A configuração padrão para aplicativos direcionados a níveis de API 23 e inferiores:
<base-config usesCleartextTraffic="true">
    <trust-anchors>
        <certificates src="system" />
        <certificates src="user" />
    </trust-anchors>
</base-config>

<domain-config>

sintaxe:
<domain-config usesCleartextTraffic=["true" | "false"]>
    ...
</domain-config>
Pode conter:
1 ou mais <domain>
0 ou 1 <trust-anchors>
0 ou 1 <pin-set>
Qualquer número de <domain-config> aninhados
Descrição
A configuração usada para conexões com destinos específicos, conforme é definido pelos elementos {@code domain}.

Observe que, se vários elementos {@code domain-config} cobrirem um destino, a configuração com a regra de domínio correspondente mais específica (mais longa) será usada.

<domain>

sintaxe:
<domain includeSubdomains=["true" | "false"]>example.com</domain>
Atributos:
{@code includeSubdomains}
Se {@code "true"}, a regra de domínio corresponderá ao domínio e a todos os subdomínios, incluindo subdomínios de subdomínios. Caso contrário, a regra se aplica apenas a correspondências exatas.
Descrição:

<debug-overrides>

sintaxe:
<debug-overrides>
    ...
</debug-overrides>
Pode conter:
0 ou 1 <trust-anchors>
Descrição:
Substituições a serem aplicadas quando android:debuggable for {@code "true"}, o que normalmente ocorre em compilações de não lançamento geradas por IDEs e ferramentas de compilação. Âncoras de confiança especificadas em {@code debug-overrides} são adicionadas a todas as demais configurações e a fixação de certificados não é realizada quando a cadeia de certificados do servidor usa uma dessas âncoras de confiança somente de depuração. Se android:debuggable for {@code "false"}, esta seção será ignorada por completo.

<trust-anchors>

sintaxe:
<trust-anchors>
...
</trust-anchors>
Pode conter:
Qualquer número de <certificates>
Descrição:
Conjunto de âncoras de confiança para conexões seguras.

<certificates>

sintaxe:
<certificates src=["system" | "user" | "raw resource"]
              overridePins=["true" | "false"] />
descrição:
Conjunto de certificados X.509 para elementos {@code trust-anchors}.
atributos:
{@code src}
A fonte de certificados de CA, que pode ser um dos
  • IDs de recursos brutos que apontam para um arquivo que contém certificados X.509. Os certificados devem ser codificados em formato DER ou PEM. No caso de certificados PEM, o arquivo não deve conter dados não PEM adicionais, como comentários.
  • {@code "system"} para os certificados de CA pré-instalados do sistema
  • {@code "user"} para certificados de CA adicionados pelo usuário
{@code overridePins}

Especifica se as CAs dessa fonte ignoram a fixação de certificados. Se {@code “true”} e forem certificadas cadeias de certificados que incluam uma das CAs dessa fonte, a fixação não será realizada. Isso pode ser útil para depurar CAs ou permitir que o usuário execute ataques MiTM no tráfego seguro do seu aplicativo.

O padrão é {@code "false"} a não ser que seja especificado em um elemento {@code debug-overrides} . Nesse caso, o padrão será {@code "true"}.

<pin-set>

sintaxe:
<pin-set expiration="date">
...
</pin-set>
Pode conter:
Qualquer número de <pin>
Descrição:
Um conjunto de fixações de chave pública. Para que uma conexão segura seja confiável, uma das chaves públicas na cadeia de confiança deve estar presente no conjunto de fixações. Consulte <pin> para saber mais sobre o formato das fixações.
Atributos:
{@code expiration}
A data, no formato {@code yyyy-MM-dd}, após a qual as fixações expiram e são desativadas. Se o atributo não for definido, as fixações não expirarão.

A expiração ajuda a evitar problemas de conectividade em aplicativos que não recebem atualizações para o conjunto de fixações, por exemplo, porque o usuário desativou as atualizações do aplicativo.

<pin>

sintaxe:
<pin digest=["SHA-256"]>base64 encoded digest of X.509
    SubjectPublicKeyInfo (SPKI)</pin>
Atributos:
{@code digest}
O algoritmo de resumo usado para gerar a fixação. No momento, apenas {@code "SHA-256"} é permitido.