Certificate Pinning é um mecanismo de fixação do certificado ou chave pública do servidor, no qual a aplicação utiliza uma impressão digital previamente conhecida para verificar a conexão HTTPS. Ao contrário da cadeia de confiança padrão através de uma CA, o pinning garante que mesmo uma autoridade certificadora comprometida não possa emitir um certificado fraudulento para o seu domínio. De acordo com OWASP MSTG (2025), o Certificate Pinning faz parte da lista de controlos obrigatórios para aplicações com nível de proteção L2. A implementação inclui o armazenamento de hashes de certificados no código e a verificação em cada requisição.
Pontos Principais
Certificate Pinning é uma técnica de segurança na qual uma aplicação armazena a impressão digital de um certificado de confiança e a utiliza como único critério para estabelecer uma conexão HTTPS. No modelo TLS padrão, o cliente verifica que o certificado do servidor é assinado por uma CA raiz de confiança — qualquer uma das centenas de autoridades certificadoras pré-instaladas no sistema. O Certificate Pinning substitui esta cadeia por uma verificação direta: o certificado deve corresponder à amostra armazenada ou conter a chave pública esperada.
O problema do modelo padrão tornou-se evidente após incidentes de comprometimento de CA — DigiNotar (2011), Comodo (2011), TrustCor (2022). Se uma CA emitir um certificado fraudulento para o seu domínio, o navegador ou a aplicação aceita-o como válido. Certificate Pinning previne este ataque: mesmo um certificado fraudulento perfeitamente assinado será rejeitado porque a sua impressão digital não corresponde à fixada na aplicação.
O termo pinning vem de pin — «pino» ou «fixador»: o desenvolvedor fixa um certificado de confiança, e qualquer desvio dele bloqueia a conexão. De acordo com a pesquisa do Mitre CWE-295, a validação imprópria de certificados continua a ser um dos 10 erros de segurança mais perigosos em aplicações móveis, e o Certificate Pinning é um método direto de o prevenir.
Originalmente, o Certificate Pinning era usado em navegadores através do mecanismo HPKP (HTTP Public Key Pinning), padronizado na RFC 7469. O desenvolvedor enviava um cabeçalho HTTP Public-Key-Pins com hashes das chaves esperadas, e o navegador armazenava-as por um período determinado. No entanto, o HPKP revelou-se perigoso: um único erro de configuração podia bloquear um site durante meses. Em 2018, o Chrome deixou de suportar o HPKP, e o padrão atual passou a ser a implementação do lado do cliente — dentro de uma aplicação móvel ou extensão de navegador.
O processo de Certificate Pinning inclui três etapas principais: cálculo da impressão digital, verificação da conexão e tratamento de erros. Durante a preparação, o desenvolvedor obtém o hash SHA-256 do certificado ou chave pública do servidor de produção. Para aplicações compatíveis com GDPR e PCI DSS, também é necessário fixar as impressões digitais das CAs intermediárias na cadeia.
Com cada requisição HTTPS, a aplicação interceta o callback de autenticação TLS, extrai o certificado do servidor e calcula o seu hash SHA-256. Este hash é comparado com a lista armazenada de impressões digitais de confiança. Se houver correspondência — a conexão prossegue. Se não — a aplicação deve terminar a conexão e reportar o erro sem revelar detalhes de implementação ao atacante.
fun validateCertificate(certificate: X509Certificate,
expectedHash: String): Boolean {
val digest = MessageDigest.getInstance("SHA-256")
val hash = Base64.encodeToString(
digest.digest(certificate.publicKey.getEncoded()),
Base64.DEFAULT
).trim()
return hash == expectedHash
}
A função recebe um objeto X509Certificate do servidor e o hash esperado. Primeiro extrai a chave pública do certificado, calcula o hash SHA-256 e codifica-o em Base64. O resultado é comparado com a impressão digital esperada. Em produção, deve adicionar a verificação contra um array de 2–3 impressões digitais para suportar a rotação.
Ao implementar o pinning, é necessário escolher qual objeto criptográfico fixar. O Certificate Pinning vincula-se ao próprio certificado X.509 — ao seu número de série, período de validade e toda a cadeia. O Public Key Pinning fixa apenas a chave pública dentro do certificado, ignorando os restantes campos. Esta escolha afeta significativamente os custos operacionais.
| Critério | Certificate Pinning | Public Key Pinning |
|---|---|---|
| Objeto de fixação | Certificado X.509 completo | Chave pública RSA/ECDSA |
| Rotação | Requer atualização em cada reemissão | Não altera ao renovar o certificado com a mesma chave |
| Segurança | Vinculação de máxima precisão | Menos sensível aos detalhes |
| Flexibilidade | Baixa — os certificados mudam a cada 1–2 anos | Alta — as chaves podem durar 5–10 anos |
| Recomendação | Para sistemas críticos com atualizações controladas | Para a maioria das aplicações móveis e APIs |
Public Key Pinning é a escolha preferida para a maioria dos projetos. As chaves públicas dos servidores geralmente permanecem inalteradas ao reemitir um certificado — a empresa simplesmente assina a chave antiga com um novo certificado. Isto significa que a aplicação não requer uma atualização após uma alteração de certificado se o par de chaves não tiver mudado. O Certificate Pinning, por outro lado, é recomendado para cenários onde o desenvolvedor controla completamente tanto o servidor como o código do cliente, como em aplicações empresariais com um ciclo de atualização rigoroso.
TOFU é uma estratégia na qual o Certificate Pinning não é configurado antecipadamente, mas sim recorda o certificado na primeira conexão ao servidor. Esta abordagem é conveniente para aplicações que não sabem antecipadamente a que servidor se vão ligar. A desvantagem é a vulnerabilidade a um ataque inicial: se a primeira conexão for intercetada, um certificado fraudulento será aceite como confiável. O TOFU é utilizado em conexões SSH e em alguns protocolos P2P.
Em ambas as plataformas, o Certificate Pinning é implementado intercetando a conexão TLS ao nível da pilha de rede. Em iOS, utiliza-se o delegado URLSession ou o Alamofire ServerTrustManager. Em Android, o método preferido é o OkHttp CertificatePinner, que está integrado em clientes HTTP populares e suporta a configuração de múltiplas impressões digitais para cada domínio.
func validate(serverTrust: SecTrust,
pinnedHash: String) -> Bool {
guard let certificates = SecTrustCopyCertificateChain(serverTrust)
as? [SecCertificate] else { return false }
for certificate in certificates {
let data = SecCertificateCopyData(certificate)
var hash = Data(repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
data.withUnsafeBytes {
CC_SHA256($0.baseAddress,
CC_LONG(data.count), &hash)
}
if hash.base64EncodedString() == pinnedHash {
return true
}
}
return false
}
Na função Swift, a cadeia de certificados é extraída do serverTrust, calcula-se um hash SHA-256 para cada certificado e o resultado é comparado com o esperado. Iterar por todos os certificados da cadeia permite implementar o pinning ao nível da CA intermediária — se um certificado intermediário corresponder, a conexão é aceite. Isto proporciona flexibilidade durante a rotação de certificados folha.
Se a aplicação não utilizar OkHttp, o Certificate Pinning pode ser implementado através de um X509TrustManager personalizado. Este método requer mais código, mas oferece controlo total sobre o processo de verificação. O TrustManager substitui o método checkServerTrusted, onde o desenvolvedor verifica manualmente os certificados do servidor e decide se confia neles. É recomendado apenas para cenários específicos onde a biblioteca OkHttp não esteja disponível.
O erro mais comum é a ausência de backup pins. O desenvolvedor inclui uma única impressão digital do certificado e, quando esta expira, os utilizadores perdem a conexão em massa. A configuração mínima aceitável são duas impressões digitais: o certificado atual e um de reserva. Idealmente três: o atual, um de reserva e a impressão digital da CA raiz como fallback.
O segundo erro é armazenar os pins em texto simples no código. Um atacante com acesso a um APK ou IPA pode facilmente extrair e substituir as impressões digitais. Recomenda-se a ofuscação de hashes: dividir a string em partes, armazenar em recursos encriptados ou calcular em tempo de execução. Para Android, o ProGuard com ofuscação de constantes de string é eficaz.
O terceiro erro é fixar ao nível do certificado de desenvolvimento. Os certificados de desenvolvimento e produção são geralmente diferentes, mas os desenvolvedores frequentemente esquecem-se de mudar os pins ao compilar uma versão de lançamento. O resultado é que a aplicação de produção não consegue ligar-se ao servidor. A solução são configurações separadas de pins para debug e release através do BuildConfig ou recursos específicos de flavor.
Perguntas Frequentes
SSL Pinning é um termo geral para a vinculação a um certificado SSL/TLS. Certificate Pinning é uma implementação específica que fixa o próprio certificado X.509, e não apenas a chave pública. A diferença está no objeto de vinculação: certificado vs chave.
Recomenda-se armazenar os hashes em recursos com ofuscação através do ProGuard (Android) ou encriptados através do Keychain (iOS). Evite armazenar pins em texto simples em strings.xml ou Info.plist sem encriptação.
Com cada alteração de certificado no servidor. Recomenda-se adicionar uma nova impressão digital como backup pin 3–6 meses antes de a atual expirar e remover a antiga após a rotação. Pelo menos um backup pin é obrigatório.
Sim, através de compilação condicional: o pinning está desativado na compilação de depuração e ativado na compilação de lançamento. Use BuildConfig.DEBUG em Android ou #if DEBUG em iOS para alternar. Nunca o faça através de uma flag em tempo de execução acessível ao utilizador.
Publique imediatamente uma atualização da aplicação com novas impressões digitais nas lojas. Use um mecanismo de atualização forçada. Se os backup pins incluírem a impressão digital da CA de reserva, pode mudar temporariamente para outro domínio com um certificado diferente.
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