X25519MLKEM768 vs X25519 é a decisão de troca de chaves presente hoje em todo handshake TLS 1.3. O X25519 sozinho é rápido e minúsculo, mas não resiste a um computador quântico, o que significa que o tráfego gravado agora poderia ser descriptografado depois. O X25519MLKEM768 executa o X25519 e o ML-KEM-768 em conjunto, de modo que a sessão continua confidencial a menos que os dois sejam quebrados.
Visão geral
| X25519 | X25519MLKEM768 | |
|---|---|---|
| Grupo suportado do TLS | x25519, 29 (0x001D) | X25519MLKEM768, 4588 (0x11EC), recomendado pela IANA |
| Especificação | RFC 7748, RFC 9846 | RFC 10024 (2026), estrutura geral na RFC 9954 |
| Componentes | X25519 | ML-KEM-768 (FIPS 203) e X25519 |
| Key share do cliente | 32 bytes | 1.216 bytes (1.184 da chave de encapsulamento ML-KEM + 32) |
| Key share do servidor | 32 bytes | 1.120 bytes (1.088 do texto cifrado ML-KEM + 32) |
| Segredo compartilhado que entra no escalonamento de chaves | 32 bytes | 64 bytes (primeiro o segredo do ML-KEM, depois o do X25519) |
| Resistência quântica | Não | Sim, enquanto o ML-KEM-768 resistir |
| Segurança clássica | A do X25519 | No mínimo a do X25519, mesmo que o ML-KEM fosse quebrado |
| CPU por handshake, OpenSSL 3.6.5 | cerca de 52.000 operações X25519 por segundo | cerca de 19.000–24.000 gerações de chave, encapsulamentos ou desencapsulamentos por segundo |
| ClientHello medido abaixo | 306 bytes | 1.484 bytes |
| ServerHello medido abaixo | 122 bytes | 1.210 bytes |
Vazão medida com openssl speed em um núcleo de um Apple M4 Max; os tamanhos do handshake vêm da captura abaixo.
Por que híbrido agora
A troca de chaves está exposta à estratégia coletar agora, descriptografar depois: um adversário grava hoje sessões criptografadas e as descriptografa quando existir um computador quântico criptograficamente relevante, recuperando as chaves de sessão a partir da troca X25519 gravada. O forward secrecy não ajuda, porque cada troca gravada pode ser quebrada individualmente. Tudo cuja confidencialidade precise durar mais que a chegada de um computador assim já está em risco, e é por isso que a troca de chaves migrou primeiro, enquanto as assinaturas podem esperar mais.
O projeto híbrido também protege no sentido inverso. O ML-KEM foi padronizado em agosto de 2024 e é jovem em comparação com o X25519, então uma quebra matemática ou de implementação não é impensável. O X25519MLKEM768 concatena os dois segredos compartilhados no escalonamento de chaves (key schedule) do TLS, então um atacante precisa quebrar os dois. Neste grupo, a RFC 10024 põe o ML-KEM em primeiro lugar, tanto no key share quanto no segredo, ao contrário dos híbridos com curvas NIST (SecP256r1MLKEM768, 0x11EB, e SecP384r1MLKEM1024, 0x11ED), que põem o ECDH primeiro.
O que muda na rede
O cliente envia um key share de 1.216 bytes em vez de 32 bytes, então um ClientHello típico cresce de cerca de 300 bytes para cerca de 1,5 KB e, com todas as outras extensões de um navegador, já não cabe em um único pacote de rede. O servidor responde com um key share de 1.120 bytes. Um handshake ao vivo com a Cloudflare, capturado com o OpenSSL 3.6.5, mostra a diferença:
echo | openssl s_client -connect cloudflare.com:443 -servername cloudflare.com -groups X25519MLKEM768 -brief 2>&1 | grep -E "Protocol|group"
echo | openssl s_client -connect cloudflare.com:443 -servername cloudflare.com -groups X25519MLKEM768 -msg 2>&1 | grep -E "ClientHello|ServerHello"
echo | openssl s_client -connect cloudflare.com:443 -servername cloudflare.com -groups X25519 -msg 2>&1 | grep -E "ClientHello|ServerHello"
Protocol version: TLSv1.3
Negotiated TLS1.3 group: X25519MLKEM768
>>> TLS 1.3, Handshake [length 05cc], ClientHello
<<< TLS 1.3, Handshake [length 04ba], ServerHello
>>> TLS 1.3, Handshake [length 0132], ClientHello
<<< TLS 1.3, Handshake [length 007a], ServerHello
São 1.484 contra 306 bytes no ClientHello e 1.210 contra 122 no ServerHello. ClientHellos maiores expuseram bugs em servidores e equipamentos intermediários que presumiam que a mensagem chega em uma única leitura TCP ou em um único pacote: quando o Chrome ativou por padrão os key shares híbridos com Kyber, na versão 124 (2024), vários produtos de firewall e de proxy precisaram de correções, uma classe de problema documentada em tldr.fail. A Cloudflare e o Google relataram um aumento de alguns por cento na latência mediana do handshake por causa dos bytes extras, o que pesa muito menos que as idas e voltas economizadas pelo próprio TLS 1.3.
Situação da implantação
- Navegadores: o Chrome e o Edge oferecem o X25519MLKEM768 por padrão desde a versão 131 (novembro de 2024), o Firefox desde a 132 no desktop, e o Safari e o TLS do sistema da Apple desde o iOS 26 e o macOS 26 (2025). A versão pré-padrão
X25519Kyber768Draft00(0x6399), que eles usavam antes, está obsoleta. - Bibliotecas: o OpenSSL 3.5 (abril de 2025) envia key shares X25519MLKEM768 e X25519 por padrão; o Go 1.24 o ativa por padrão em
crypto/tls; o JDK 27 (setembro de 2026, JEP 527) o oferece em primeiro lugar por padrão; a BoringSSL, a rustls e a NSS oferecem suporte a ele. - Servidores e CDNs: a Cloudflare, o Google e outros grandes provedores o negociam com os clientes compatíveis; o nginx, o Apache e o HAProxy herdam o suporte do OpenSSL com que estão vinculados.
- SSH: o equivalente
mlkem768x25519-sha256é o padrão do OpenSSH desde a versão 10.0 (RFC 10042).
A verificação pós-quântica do navegador mostra o que o seu navegador negocia.
Quando escolher cada um
- HTTPS público e APIs: ofereça o X25519MLKEM768 em primeiro lugar e o X25519 em segundo; todo cliente moderno negocia o híbrido, e os antigos recorrem ao segundo.
- Service mesh interno e mTLS: híbrido por padrão, principalmente para dados que precisam permanecer confidenciais por muito tempo.
- Implantações orientadas ao FIPS:
SecP256r1MLKEM768ouSecP384r1MLKEM1024, se a lista de algoritmos aprovados do seu módulo exigir curvas NIST; o X25519MLKEM768 se qualifica onde o ML-KEM é o componente aprovado. - Links restritos em que cada pacote conta: meça primeiro; o híbrido acrescenta um pacote em cada sentido, o que costuma ser aceitável.
- X25519 sozinho: só para pares que não conseguem usar o híbrido, nunca como escolha deliberada em novas implantações.
Notas de migração
- Atualize a biblioteca TLS (OpenSSL 3.5 ou posterior, Go 1.24 ou posterior, BoringSSL ou rustls atuais); com o OpenSSL 3.5, os grupos padrão já incluem o híbrido.
- Se você define os grupos explicitamente, adicione o híbrido: por exemplo,
ssl_ecdh_curve X25519MLKEM768:X25519:prime256v1;no nginx ouGroups = X25519MLKEM768:X25519:P-256em um arquivo de configuração do OpenSSL. - Teste o caminho, não só o servidor: balanceadores de carga, WAFs e proxies que inspecionam o TLS precisam lidar com um ClientHello dividido entre pacotes e leituras; teste de novo depois das atualizações deles.
- Verifique o que é negociado com
openssl s_client -groups X25519MLKEM768ou com as ferramentas de desenvolvedor do navegador, e monitore a proporção de handshakes híbridos. - Planeje o lado das assinaturas separadamente: o híbrido protege apenas a confidencialidade; os certificados e as assinaturas do handshake continuam clássicos até que as assinaturas pós-quânticas cheguem à WebPKI.
Referências
- RFC 10024, mecanismos híbridos PQ/T de acordo de chaves para o TLS 1.3
- RFC 9954, troca de chaves híbrida no TLS 1.3
- FIPS 203, ML-KEM
- RFC 7748, X25519
- Registro de grupos suportados do TLS (TLS Supported Groups) na IANA
- Notas de versão do OpenSSL 3.5
- tldr.fail: bugs de fragmentação do ClientHello
- NIST IR 8547 ipd §4.1.2 (estabelecimento de chaves)