SSL Pinning é uma técnica de segurança onde o aplicativo verifica o certificado do servidor contra uma impressão digital ou certificado previamente conhecido, em vez de confiar na cadeia de confiança da CA. Ao contrário da verificação padrão, o pinning impede a interceptação de tráfego através de centros de certificação raiz fraudulentos. De acordo com o OWASP Mobile Security Testing Guide (2025), esta técnica está entre os 3 controles recomendados para proteção contra ataques MITM. Sem pinning, um atacante com um certificado raiz fraudulento pode descriptografar todo o tráfego HTTPS do aplicativo.
Principais conclusões
SSL Pinning é um mecanismo de segurança onde um aplicativo móvel ou web lembra um certificado de servidor confiável ou chave pública e rejeita qualquer conexão cujo certificado não corresponda ao armazenado. No esquema HTTPS padrão, o cliente verifica o certificado através de uma cadeia de confiança até a CA raiz — qualquer CA pode assinar um certificado para qualquer domínio. SSL Pinning elimina esta fraqueza: em vez de confiar em centenas de CAs, o aplicativo confia apenas em um certificado específico.
O problema da verificação padrão é que qualquer uma das centenas de CAs raiz pode emitir um certificado válido para o seu domínio — acidentalmente ou sob coação. Um atacante que obtém acesso a um proxy corporativo com seu próprio certificado raiz pode realizar um ataque MITM sem aviso do navegador. SSL Pinning fecha esta vulnerabilidade: mesmo que uma CA emita um certificado fraudulento, o aplicativo o rejeitará porque a impressão digital não corresponde à registrada.
Em aplicativos móveis, o SSL Pinning é especialmente importante porque os dispositivos frequentemente operam em redes não seguras — Wi-Fi público, proxies corporativos com inspeção de tráfego, pontos de acesso infectados. De acordo com o Verizon Mobile Security Index (2025), mais de 60% das violações de dados em aplicativos móveis estão relacionadas à interceptação de tráfego na camada de transporte.
Os aplicativos móveis transmitem dados sensíveis — tokens de autenticação, informações de pagamento, dados pessoais dos usuários. Sem proteção adicional, o HTTPS pode ser comprometido através da substituição do certificado raiz no dispositivo — por exemplo, após instalar um perfil corporativo ou aplicativo malicioso. SSL Pinning garante que mesmo se uma CA raiz fraudulenta for instalada no dispositivo, o aplicativo continuará verificando o certificado contra sua própria lista branca.
O processo de SSL Pinning consiste em três etapas: captura da impressão digital, verificação na conexão e tratamento de erros. Durante o desenvolvimento, o engenheiro obtém a impressão digital SHA-256 do certificado do servidor (openssl x509 -fingerprint -sha256) e a incorpora no código do aplicativo ou arquivo de configuração. Em cada solicitação HTTPS, o aplicativo calcula a impressão digital do certificado recebido e a compara com a armazenada — se os valores não coincidirem, a conexão é encerrada.
A primeira etapa é o pinning em tempo de compilação: o desenvolvedor conhece os certificados do servidor antecipadamente e incorpora seus hashes. A segunda etapa é o pinning na primeira conexão (trust on first use, TOFU): o aplicativo lembra o certificado na primeira solicitação e o usa para verificar todas as subsequentes. TOFU é conveniente para ambientes dinâmicos, mas é vulnerável no primeiro ataque — se a primeira conexão já estiver interceptada, o certificado fraudulento será aceito como confiável.
Um detalhe crítico são os backup pins. Os certificados têm uma data de validade e, quando são substituídos, o aplicativo sem atualização perderá a conexão com o servidor. Os engenheiros incluem 2–3 impressões digitais adicionais — por exemplo, a impressão digital de um certificado de backup e a impressão digital da CA raiz. Se o certificado principal mudar, o aplicativo verifica contra os backup pins e a conexão continua funcionando.
# Obtendo a impressão digital SHA-256 do certificado
openssl s_client -connect example.com:443 </dev/null 2>/dev/null | \
openssl x509 -pubkey -noout | \
openssl pkey -pubin -outform der | \
openssl dgst -sha256 -binary | \
base64
Existem duas abordagens principais para implementar o pinning: fixação ao certificado completo (certificate pinning) e fixação à chave pública (public key pinning). Cada abordagem tem seus próprios pontos fortes e limitações que afetam a segurança e a manutenibilidade.
| Tipo | Objeto de fixação | Flexibilidade | Segurança |
|---|---|---|---|
| Certificate Pinning | Certificado X.509 completo | Baixa — requer atualização quando o certificado muda | Alta — fixação precisa |
| Public Key Pinning | Chave pública do certificado | Média — a chave pode estar em um novo certificado | Alta — menos sensível aos detalhes do certificado |
| Hash Pinning | Hash SHA-256 do certificado ou chave | Alta — pode mudar certificados sem mudar a chave | Média — depende da força do hash |
A fixação de certificado é o método mais rigoroso. O aplicativo armazena uma cópia do certificado confiável ou sua impressão digital SHA-256 e a compara com o certificado do servidor em cada conexão HTTPS. Este método fornece máxima segurança, mas cria problemas durante a rotação — os certificados geralmente duram 1–2 anos, após os quais é necessária uma atualização forçada do aplicativo. Recomendado para sistemas críticos com ciclo de atualização controlado.
A fixação de chave pública é uma abordagem mais flexível. Em vez de todo o certificado, o aplicativo lembra apenas a chave pública RSA ou ECDSA do servidor. A chave pode permanecer inalterada quando o certificado for reemitido, se a empresa usar o mesmo par de chaves. Isso reduz a frequência de atualizações do aplicativo. No entanto, se a chave for comprometida, será necessária uma substituição em cascata em todos os clientes.
Na plataforma Apple, o SSL Pinning é implementado através do delegate do URLSession. O desenvolvedor cria uma classe que implementa o protocolo URLSessionDelegate e sobrescreve o método didReceive challenge, onde verifica manualmente o certificado do servidor contra as impressões digitais armazenadas. Uma abordagem alternativa é usar Alamofire com ServerTrustManager, que simplifica a configuração.
class SSLPinningDelegate: NSObject, URLSessionDelegate {
let pinnedHash = "sha256/Wi24BE7j5qLk0iLvPq6ePEsVRqZ1yW0F6wLg="
func urlSession(_ session: URLSession,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
guard let serverTrust = challenge.protectionSpace.serverTrust
else { return completionHandler(.cancelAuthenticationChallenge, nil) }
if validate(serverTrust, pinnedHash) {
completionHandler(.useCredential, URLCredential(trust: serverTrust))
} else {
completionHandler(.cancelAuthenticationChallenge, nil)
}
}
}
No exemplo, o delegate recebe uma solicitação de autenticação do URLSession, extrai serverTrust do challenge e compara a impressão digital SHA-256 do certificado com a armazenada. Se a impressão digital coincidir — a conexão prossegue, caso contrário, o challenge é rejeitado. Para produção, vale a pena adicionar verificação de múltiplos backup pins e registro de erros para monitoramento.
A partir do iOS 14, a Apple adicionou suporte integrado para Certificate Pinning através do Info.plist. O desenvolvedor especifica os certificados confiáveis na chave NSAppTransportSecurity com o sub-dicionário NSPinnedDomains. Esta abordagem não requer escrever código, mas é menos flexível — é impossível alterar dinamicamente os pins ou registrar erros de verificação.
No Android, existem três formas principais de implementar SSL Pinning: através do CertificatePinner da biblioteca OkHttp, através do Network Security Config em XML, e através de verificação personalizada em HttpsURLConnection. OkHttp é a abordagem mais popular e recomendada, usada em Retrofit e outros clientes HTTP.
val certificatePinner = CertificatePinner.Builder()
.add("api.example.com",
"sha256/Wi24BE7j5qLk0iLvPq6ePEsVRqZ1yW0F6wLg=")
.add("api.example.com",
"sha256/FiPq6ePEsVRqZ1yW0F6wLgWi24BE7j5qLk0iL=") // backup pin
.build()
val client = OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build()
Na configuração do OkHttp, o desenvolvedor especifica o domínio e uma ou mais impressões digitais SHA-256. Na primeira impressão digital, o OkHttp compara o certificado do servidor com os pins especificados. Se não houver correspondência, o cliente lança SSLPeerUnverifiedException. Um backup pin é obrigatório — sem ele, quando o certificado muda, as solicitações à API começarão a falhar imediatamente.
O Android suporta Certificate Pinning declarativo através de configuração XML a partir da API 24. O arquivo res/xml/network_security_config.xml contém uma lista de domínios e suas impressões digitais. Este método é conveniente para configurações estáticas, mas não permite implementar TOFU ou lógica de verificação personalizada com registro de anomalias.
<!-- res/xml/network_security_config.xml -->
<network-security-config>
<domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">api.example.com</domain>
<pin-set expiration="2027-12-31">
<pin digest="SHA-256">
Wi24BE7j5qLk0iLvPq6ePEsVRqZ1yW0F6wLg=</pin>
<pin digest="SHA-256">
FiPq6ePEsVRqZ1yW0F6wLgWi24BE7j5qLk0iL=</pin>
</pin-set>
</domain-config>
</network-security-config>
O SSL Pinning aumenta significativamente a segurança de um aplicativo móvel, mas introduz complexidades operacionais. A principal vantagem é a proteção contra ataques MITM mesmo quando as CAs raiz estão comprometidas. O aplicativo confia apenas naqueles certificados explicitamente especificados pelo desenvolvedor, não em toda a infraestrutura de autoridades de certificação públicas. Isso é especialmente crítico para aplicativos financeiros, mensageiros e aplicativos com dados sensíveis.
A principal desvantagem é a complexidade da rotação de certificados. Se um certificado expirar ou for revogado, os usuários sem atualização do aplicativo perdem a conexão. Isso é resolvido através de backup pins e um mecanismo de atualização gradual: o novo aplicativo conhece tanto os certificados antigos quanto os novos, e após uma atualização completa dos usuários, o pin antigo é removido do código. Recomenda-se incluir pelo menos 2 backup pins — um para o certificado atual, um para o futuro.
Outro compromisso é a impossibilidade de usar proxies públicos para depuração de tráfego (Charles Proxy, Burp Suite) sem desabilitar o pinning. Isso complica a depuração de solicitações de rede durante o desenvolvimento. A solução é a compilação condicional: o pinning está desabilitado nas compilações de debug e habilitado nas de release. A OWASP recomenda usar o sinalizador BuildConfig.DEBUG para alternar.
| Aspecto | Vantagem | Desvantagem |
|---|---|---|
| Segurança | Proteção contra MITM através de CAs fraudulentas | Complexidade quando uma chave é comprometida |
| Manutenção | Controle explícito de confiança | Rotação requer atualização do aplicativo |
| Depuração | Conexão garantida com o servidor correto | Bloqueia proxies de depuração |
Perguntas frequentes
A verificação HTTPS padrão confia em qualquer certificado assinado por uma CA raiz conhecida. SSL Pinning confia apenas em um certificado específico ou chave — se uma CA emitir um certificado fraudulento, o aplicativo o rejeitará.
Os certificados geralmente duram 1–2 anos. Recomenda-se atualizar os pins 3–6 meses antes da expiração do certificado atual, adicionando a nova impressão digital como backup pin e removendo a antiga após a rotação.
Sim, mas é preciso considerar que a CDN pode alterar certificados ao alternar entre servidores edge. Recomenda-se fixar-se à chave pública em vez de a um certificado específico e usar múltiplos backup pins.
A conexão é encerrada com um erro — no Android é SSLPeerUnverifiedException, no iOS o challenge é rejeitado com .cancelAuthenticationChallenge. O aplicativo deve tratar corretamente este erro e notificar o usuário.
Não, mas a OWASP o recomenda para aplicativos que lidam com dados sensíveis: bancos, saúde, sistemas corporativos. Para aplicativos simples de apenas leitura, a verificação HTTPS padrão com certificados EV geralmente é suficiente.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também