O que é SSL Pinning e por que ele importa
Em uma conexão HTTPS comum, o Android valida o certificado do servidor contra a lista de Autoridades Certificadoras (CAs) confiáveis do sistema operacional. Isso é suficiente para a maioria dos casos, mas cria um vetor de ataque: qualquer CA comprometida — ou um certificado instalado pelo usuário/atacante — pode ser usado para interceptar o tráfego.
SSL Pinning resolve isso fixando (pinando) o certificado ou a chave pública esperada diretamente no código do aplicativo. Se o certificado apresentado pelo servidor não corresponder ao que está "pinado", a conexão é recusada — mesmo que seja tecnicamente válido para o sistema operacional.
Isso é especialmente crítico em apps financeiros, de saúde e qualquer sistema que trafegue dados sensíveis.
Tipos de SSL Pinning
Certificate Pinning
Fija o certificado completo (arquivo .cer / .pem). É mais restritivo, mas exige atualização do app a cada renovação de certificado.
Public Key Pinning (recomendado)
Fija apenas a chave pública do certificado. Como a chave pública muda raramente (mesmo com renovação de certificado), essa abordagem requer menos manutenção e é considerada a melhor prática.
Implementação com OkHttp e CertificatePinner
A forma mais comum de implementar pinning no Android é via OkHttp, a biblioteca HTTP padrão do ecossistema.
1. Obtenha o hash da chave pública
# Extrai o hash SHA-256 da chave pública do certificado
openssl s_client -connect api.seudominio.com.br:443 -servername api.seudominio.com.br \
</dev/null 2>/dev/null \
| openssl x509 -pubkey -noout \
| openssl pkey -pubin -outform der \
| openssl dgst -sha256 -binary \
| base64
O resultado será algo como: abc123XYZ456def789GHI012jkl345MNO678pqr901STU=
2. Configure o CertificatePinner
import okhttp3.CertificatePinner
import okhttp3.OkHttpClient
val certificatePinner = CertificatePinner.Builder()
.add(
"api.seudominio.com.br",
"sha256/abc123XYZ456def789GHI012jkl345MNO678pqr901STU=",
"sha256/BACKUP_HASH_AQUI=" // sempre inclua um pin de backup
)
.build()
val client = OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build()
3. Sempre inclua um pin de backup
Se o servidor precisar trocar de chave e você não tiver um pin de backup no app, todos os usuários da versão com o pin antigo perderão acesso até atualizarem o app. Por isso:
- Gere antecipadamente um par de chaves de backup
- Inclua o hash da chave pública de backup no
CertificatePinner - Antes de rotacionar a chave principal, certifique-se de que a versão com o backup publicada alcançou a maioria dos usuários
Implementação via Network Security Config (Android 7+)
Outra abordagem, sem código Kotlin/Java, é usar o arquivo XML de configuração de segurança de rede:
<!-- res/xml/network_security_config.xml -->
<network-security-config>
<domain-config>
<domain includeSubdomains="false">api.seudominio.com.br</domain>
<pin-set expiration="2026-12-31">
<pin digest="SHA-256">abc123XYZ456def789GHI012jkl345MNO678pqr901STU=</pin>
<!-- pin de backup obrigatório -->
<pin digest="SHA-256">BACKUP_HASH_AQUI=</pin>
</pin-set>
</domain-config>
</network-security-config>
Declare no AndroidManifest.xml:
<application
android:networkSecurityConfig="@xml/network_security_config"
...>
Vantagem: mais simples, configuração declarativa.
Desvantagem: a data de expiração exige atualização do app antes de vencer.
Proteção contra bypass
SSL Pinning por si só não é suficiente se o app puder ser manipulado. Em ambientes de alta segurança, combine com:
- Root Detection — verificar se o dispositivo está rooteado (
RootBeer,SafetyNet, Play Integrity) - Anti-debugging — detectar se um debugger está anexado
- Obfuscação de código — usar ProGuard/R8 para dificultar engenharia reversa
- Play Integrity API — atestar integridade do dispositivo e do app no servidor
Testando o pinning
Para validar que o pinning está funcionando, use o mitmproxy ou o Burp Suite:
- Instale o certificado do proxy no Android como CA confiável do usuário
- Configure o proxy no dispositivo
- Tente fazer uma requisição pelo app — ela deve ser recusada se o pinning estiver correto
Se a requisição passar, o pinning não está funcionando como esperado.
Conclusão
SSL Pinning é uma camada essencial de defesa em profundidade para apps que lidam com dados sensíveis. A abordagem de Public Key Pinning com OkHttp é a mais robusta e fácil de manter, desde que você sempre inclua pins de backup antes de qualquer rotação de chaves.
Combinado com Play Integrity, root detection e obfuscação de código, você eleva significativamente a barreira para ataques de interceptação de tráfego.
Gostou do conteúdo?
Se você está construindo um sistema nesta área, podemos ajudar. Fale com um especialista.
Agendar Consultoria