page.title=Configuração de segurança de rede page.keywords=androidn,security,network page.image=images/cards/card-nyc_2x.jpg @jd:body
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:
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>
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).
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}.
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.
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>
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>
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>
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>
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>
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.
<base-config>
<domain-config>
<debug-overrides>
<base-config usesCleartextTraffic=["true" | "false"]> ... </base-config>
<trust-anchors>
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 usesCleartextTraffic=["true" | "false"]> ... </domain-config>
<domain>
<trust-anchors>
<pin-set>
<domain-config>
aninhadosObserve 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 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 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 expiration="date"> ... </pin-set>
<pin>
<pin>
para saber mais sobre o formato das fixações.
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 digest=["SHA-256"]>base64 encoded digest of X.509 SubjectPublicKeyInfo (SPKI)</pin>