Chaves Fracas da eMudhra: 5 Mitos de PKI Desmascarados
Uma CA confiável distribuiu chaves privadas quebráveis em milissegundos. Testamos cinco crenças sobre PKI, geração de chaves e auditoria no caso eMudhra.

Uma das chaves privadas da autoridade certificadora da eMudhra é o número 4. Não um número de 384 bits que começa com 4 — apenas 4, com 47 bytes zero preenchendo o resto para parecer respeitável. Esta é uma falha de geração de chave de autoridade certificadora do tipo que eu diria ser impossível, e ela sobreviveu a auditorias, à certificação cruzada pela Sectigo e a dezessete meses em infraestrutura quase de produção, até que alguém tentou o óbvio: força bruta em um único byte. Aqui estão cinco crenças sobre PKI que este incidente mata de vez.
Mito 1: "Um certificado estruturalmente válido é um certificado seguro"
Cada verificação automatizada no pipeline disse que esses certificados estavam ok. E estavam certas, num sentido estreito e inútil. O ponto público correspondente a d = 4 é um ponto perfeitamente válido na curva P-384. A codificação ASN.1 é interpretada. A assinatura é verificada. A cadeia se constrói. Todo linter, todo validador estrutural, todo checklist de conformidade que percorre um certificado e confirma que ele está bem formado vai deixá-los passar, porque eles estão bem formados.
Aí está a armadilha. A validação estrutural responde à pergunta "este é um certificado formatado corretamente?" Ela não responde "a chave interna foi gerada corretamente?" Para chaves de curva elíptica, essas são propriedades quase completamente independentes. A chave privada é apenas um escalar d; a chave pública é d × G, onde G é o ponto gerador da curva. Todo o argumento de segurança é que recuperar d a partir do ponto público exige resolver o problema do logaritmo discreto — mas só se d tiver sido escolhido no espaço completo de 384 bits. Escolha d em 8 bits e o problema "impossível" vira um laço que roda no máximo 255 iterações.
Nada no certificado resultante sugere isso. O ponto público derivado de d = 4 parece exatamente tão aleatório quanto um derivado de uma chave gerada corretamente. Você não consegue perceber a olho nu. Não dá para detectar com lint. A única forma de saber é testar valores pequenos e padrões fracos conhecidos — que foi exatamente o que aconteceu: o pesquisador rodou a suíte de testes paranoid_crypto do Google contra o corpus do Common CA Database, direto da caixa, e obteve um acerto. Uma verificação que leva milissegundos em um notebook, contra chaves que ancoram a confiança de navegadores reais.
Então a primeira lição: validade é necessária e está longe de ser suficiente. Se seus testes de PKI param em "o certificado faz parse e encadeia", você está testando o envelope e ignorando o conteúdo.
Mito 2: "Requisitos básicos e auditorias pegam bugs de geração de chaves"
Autoridades certificadoras operam sob os Baseline Requirements do CA/Browser Forum e são auditadas segundo os critérios WebTrust ou ETSI. Há documentação de cerimônia, requisitos de HSM, requisitos de tamanho de chave. As chaves da eMudhra tinham o tamanho certo — 384 bits no papel. A lacuna da auditoria é que a conformidade verifica a representação da chave, não a entropia do processo que a produziu. Uma chave preenchida com 47 bytes zero ainda ocupa 48 bytes em disco.
Segundo o relato da própria eMudhra, publicado no ticket de incidente da Mozilla, a causa raiz parece uma comédia de humor negro: um bug no script da cerimônia gerou um segundo par de chaves fraco no HSM; os dois pares tinham nomes parecidos; uma pessoa escolheu o errado para o CSR. Três falhas separadas — um bug de script, uma colisão de nomes e um erro de seleção — e em nenhum momento algum controle perguntou "essa chave realmente tem a entropia pela qual pagamos ao HSM?"
Essa é a parte que deveria preocupar todo engenheiro que mantém sua própria PKI interna. Se uma autoridade certificadora publicamente confiável, com programas de raiz no seu pé e auditorias no calendário, consegue distribuir uma chave privada igual a 4, o que há dentro do seu backend PKI do Vault ou dos seus modelos do Active Directory Certificate Services? A correção é barata e não há desculpa para não fazê-la. Depois de gerar qualquer chave, e antes de assinar qualquer coisa com ela, passe-a pelo paranoid_crypto ou, no mínimo, por uma verificação de sanidade trivial:
from cryptography.hazmat.primitives.asymmetric import ec
CURVE_ORDER_BITS = 384
def sanity_check_private_key(key: ec.EllipticCurvePrivateKey) -> None:
d = key.private_numbers().private_value
# Reject keys whose effective entropy is far below the curve size.
# A healthy P-384 key should have a bit length close to 384.
if d.bit_length() < CURVE_ORDER_BITS - 32:
raise ValueError(
f"Suspiciously small private scalar: {d.bit_length()} bits"
)
# Also reject known bad values outright.
if d < 2**16:
raise ValueError("Private scalar is trivially brute-forceable")
Trinta segundos de trabalho. Teria pego todas as oito chaves da eMudhra. Auditorias verificam que os processos existem; não verificam se os processos funcionaram em uma terça-feira qualquer de abril. Só o teste da saída faz isso.
Mito 3: "Uma chave de CA comprometida pode ser contida"
Quando uma chave de CA é "comprometida" no sentido usual, existe um ladrão. Alguém extraiu a chave em um momento específico, e você consegue raciocinar sobre o raio de impacto: certificados emitidos após o roubo, por quem tem a chave roubada. Feio, mas limitado. Já escrevemos sobre o que acontece quando o comprometimento de uma CA intermediária racha uma cadeia de confiança, e o roteiro padrão — revogar, remover a confiança, reemitir — pressupõe um antes e um depois.
Este incidente não tem antes nem depois. A chave estava efetivamente pública desde o momento em que o certificado foi criado, porque qualquer um que olhasse para o certificado conseguia recuperá-la em milissegundos. Não há um evento de roubo para delimitar. A janela é toda a vida útil dos certificados — de abril de 2025 em diante — e não há como saber quem, se alguém, atravessou a porta aberta. A declaração da eMudhra de que as intermediárias não emitiram certificados de entidade final, corroborada pelos logs do Certificate Transparency, é genuinamente tranquilizadora quanto ao que essas CAs fizeram. Mas não diz nada sobre o que alguém com d=4 poderia ter feito oportunisticamente em algum caminho de rede.
Pior: a resposta em si não consegue ser totalmente efetiva. Chrome e Firefox bloquearam as intermediárias em horas via CRLSet e OneCRL, e ambos exigem registro em CT, então certificados TLS forjados nunca seriam validados nesses navegadores de qualquer forma. Ótimo. Mas essa proteção termina na fronteira do navegador, o que nos leva ao próximo mito.
Mito 4: "Se os navegadores estão seguros, o ecossistema está seguro"

Navegadores são o cenário ideal no ecossistema TLS, e representam uma minoria dos clientes TLS que importam operacionalmente para você. Pense no que de fato faz conexões HTTPS na sua infraestrutura: curl, o requests do Python, Node, binários em Go, serviços Java, git, gerenciadores de pacotes, SDKs de nuvem. Esses clientes compartilham três características que se combinam mal aqui: confiam em um bundle de CAs em disco, não verificam revogação por padrão e não verificam o Certificate Transparency. As três proteções que salvaram os usuários do Chrome estão ausentes.
Scott Helme demonstrou isso de forma concreta: com um certificado forjado para api.stripe.com encadeado a uma das intermediárias fracas da eMudhra, o curl padrão reportou SSL certificate verify ok, o Python completou o handshake, o Node informou a conexão como autorizada e o CryptoAPI do Windows aceitou a cadeia. Em todas as máquinas Linux e macOS testadas. Um certificado forjado para qualquer hostname, aceito pelas ferramentas padrão nas quais seus scripts de deploy e runners de CI são construídos. Isso não é um problema do navegador; é um problema da sua infraestrutura.
O mapa de exposição é pior do que a maioria imagina:
- Instaladores via curl | sh e atualizadores automáticos. rustup, nvm, o instalador do Homebrew, incontáveis páginas "install.sh". Um certificado forjado aqui significa executar código do atacante, frequentemente como root.
- Pipelines de CI/CD. Os runners buscam dependências e publicam artefatos enquanto mantêm credenciais de nuvem e chaves de assinatura, muitas vezes em imagens base desatualizadas.
- Tráfego servidor a servidor. Webhooks de pagamento, trocas de tokens OAuth, chamadas de SDKs de nuvem carregando segredos em cabeçalhos.
- Dispositivos IoT e embarcados. Firmware congelado com bundles de CA que não mudarão até os certificados expirarem — em julho de 2039.
- Assinatura de código no Windows. Duas das oito chaves fracas pertenciam a CAs de assinatura de código; malware assinado com elas parece software de um publicador legítimo.
O conselho prático é chato e correto: atualize tudo que distribui um bundle de CAs. O pacote ca-certificates do seu SO, certifi, Node, Homebrew — e reconstrua suas imagens de container assim que as imagens base incorporarem a desconfiança, porque as camadas guardam memória. A parte não acionável é o dispositivo que você não consegue atualizar. Aquela smart TV vai confiar numa chave igual a 4 por mais uma década e meia. Se você precisava de mais um argumento para segmentar sua rede de dispositivos IoT, aí está.
Mito 5: "Alguém certamente já está verificando isso"
A linha mais silenciosamente reveladora do incidente veio do pesquisador: a descoberta surgiu ao rodar o paranoid_crypto contra o corpus da CCADB como um teste rápido de corpus antes de passar para os certificados de assinantes. A fruta mais fácil de pegar. Nas palavras do próprio pesquisador: "A maior parte do meu tempo foi gasta revisando o básico que todo mundo presumia que outra pessoa já tinha feito — um erro crítico que nunca se deve cometer perto de segurança."
Leia de novo. Oito chaves privadas de CA — as joias da coroa de uma autoridade publicamente confiável, com certificação cruzada na raiz AAA Certificate Services da Sectigo — ficaram vulneráveis a força bruta por dezessete meses, e foram encontradas não por um auditor, não por um programa de raiz, não pela própria CA, mas por uma pessoa rodando uma ferramenta de código aberto direto da caixa. O ecossistema coletivamente presumiu que o básico estava coberto. Ninguém cobriu o básico.
Esse é um padrão mais amplo na infraestrutura de segurança, e é por isso que continuo insistindo em engenharia defensiva — sistemas que resistem a catástrofes em vez de sistemas que presumem operação correta. As verificações que teriam pego isso são quase constrangedoramente baratas:
- Rode
paranoid_cryptoou verificações equivalentes de chaves fracas em cada chave na geração e em cada CSR antes de assinar. - Verifique a entropia empiricamente: confira o tamanho em bits do escalar privado e rejeite qualquer coisa com entropia efetiva implausivelmente baixa, como no exemplo de código acima.
- Teste a cerimônia, não apenas a configuração. Faça ensaios das suas cerimônias de chaves e inspecione os artefatos reais produzidos, incluindo qual objeto nomeado do HSM acaba no CSR.
- Monitore continuamente os certificados emitidos, não apenas os seus modelos. O certificado é a verdade de referência; tudo o que vem antes é intenção.
O certificado é a verdade de referência. Tudo o que vem antes — scripts, cerimônias, auditorias — é apenas intenção.
Oito Bits Bastam
Há algo quase reconfortante em uma catástrofe com causa boba. Um bug de script, duas chaves com nomes parecidos num HSM, uma pessoa escolhendo a errada — nenhum estado-nação, nenhuma criptoanálise inovadora, só um episódio dos Três Patetas com um pavio de dezessete meses. Mas a bobagem é o alerta. Se o elo mais fraco de uma CA publicamente confiável pode ser um único byte, então a força da sua PKI não é definida pela escolha da sua curva ou pelo orçamento do seu HSM. É definida por alguém, em algum ponto do pipeline, ter de fato testado a saída.
Os fornecedores de navegadores fizeram sua parte em horas. O resto cabe a nós: audite a sua própria geração de chaves, rode as verificações baratas, atualize todo bundle de CA que você conseguir alcançar e segmente os dispositivos que não consegue atualizar. E pare de presumir que outra pessoa já verificou o básico. Em segurança, essa é a suposição mais cara que existe.


