#!/intro
A adoção da criptografia pós-quântica está progressivamente a chegar às plataformas utilizadas em ambientes reais. O OpenSSL 3.5 passou a disponibilizar nativamente os algoritmos ML-KEM, ML-DSA e SLH-DSA, enquanto o OpenSSH 10 adotou como método preferencial de troca de chaves o mlkem768x25519-sha256, combinando ML-KEM-768 com X25519.
O ecossistema Java tem seguido a mesma evolução. O JDK 21 introduziu uma API genérica para mecanismos de encapsulamento de chaves, preparando a Java Cryptography Architecture para a integração deste tipo de primitivas. O JDK 24 acrescentou suporte nativo para ML-KEM e ML-DSA e o JDK 27 leva agora ML-KEM diretamente para o TLS 1.3 através de grupos híbridos de troca de chaves.
O SunJSSE passa a suportar X25519MLKEM768, SecP256r1MLKEM768 e SecP384r1MLKEM1024, os três grupos definidos na RFC 10024. O primeiro encontra-se ativado por omissão e ocupa a posição de maior preferência na configuração predefinida do provider.
A abordagem combina uma componente clássica baseada em ECDHE com uma componente pós-quântica baseada em ML-KEM. Os segredos produzidos pelos dois mecanismos são combinados e utilizados como entrada no processo de derivação das chaves da sessão TLS 1.3.
Esta evolução permite que aplicações Java baseadas nas APIs normais de TLS passem a beneficiar de proteção híbrida pós-quântica diretamente através da plataforma, mantendo a integração habitual com a Java Cryptography Architecture e com o Java Secure Socket Extension.
Veja também Criptografia pós-quântica no OpenSSL, Criptografia pós-quântica no OpenSSH e Criptografia pós-quântica: os novos algoritmos.
> confidencialidade
A urgência da transição para criptografia pós-quântica não começa apenas quando existir um computador quântico capaz de comprometer os algoritmos assimétricos atualmente utilizados. O risco começa antes, porque comunicações cifradas podem ser recolhidas hoje e armazenadas durante anos na expectativa de virem a ser decifradas no futuro.
Este modelo é habitualmente designado por harvest now, decrypt later. Um adversário pode conservar tráfego TLS atualmente protegido por mecanismos clássicos de troca de chaves e aguardar até dispor de capacidade suficiente para quebrar os pressupostos matemáticos em que esses mecanismos assentam.
O problema é particularmente relevante quando a informação tem de permanecer confidencial durante períodos prolongados. Comunicações intercetadas hoje não podem ser novamente protegidas depois de terem sido recolhidas, pelo que a resistência perante futuros ataques quânticos deve existir no momento em que a sessão é estabelecida.
É neste contexto que ML-KEM assume especial importância. A sua integração na troca de chaves permite acrescentar uma componente resistente a ataques quânticos às sessões estabelecidas atualmente, protegendo informação cujo valor possa prolongar-se por muitos anos.
A estratégia híbrida permite fazer esta transição sem abandonar de imediato os mecanismos clássicos amplamente analisados. O segredo utilizado pela sessão passa a depender de duas componentes baseadas em famílias criptográficas diferentes, reduzindo a dependência exclusiva dos algoritmos vulneráveis à computação quântica.
> suporte
A integração da criptografia pós-quântica no Java assenta na Java Cryptography Architecture (JCA), que separa as interfaces utilizadas pelas aplicações das implementações fornecidas pelos diferentes providers criptográficos.
O primeiro passo ocorreu no JDK 21 através do JEP 452, com a introdução da API javax.crypto.KEM. Esta API fornece uma interface genérica para mecanismos de encapsulamento de chaves, permitindo aos providers disponibilizar diferentes implementações através de um modelo comum.
O JDK 24 acrescentou a implementação de ML-KEM através do JEP 496. O provider SunJCE disponibiliza ML-KEM, ML-KEM-512, ML-KEM-768 e ML-KEM-1024 através dos serviços KEM, KeyFactory e KeyPairGenerator.
Na mesma versão, o JEP 497 integrou ML-DSA. O provider SUN disponibiliza ML-DSA, ML-DSA-44, ML-DSA-65 e ML-DSA-87 através dos serviços KeyFactory, KeyPairGenerator e Signature.
Esta integração mantém o modelo habitual da JCA. Uma aplicação solicita um determinado serviço criptográfico e a plataforma seleciona um provider registado que disponibilize o algoritmo pretendido.
A versão instalada pode ser confirmada através de:
java -version
Os algoritmos pós-quânticos disponíveis na JVM podem ser consultados diretamente através da JCA. No JShell:
import java.security.Security;
Security.getAlgorithms("KEM").stream()
.filter(a -> a.startsWith("ML-KEM"))
.sorted()
.forEach(System.out::println);
Security.getAlgorithms("Signature").stream()
.filter(a -> a.startsWith("ML-DSA"))
.sorted()
.forEach(System.out::println);
Num JDK que disponibilize estas implementações, a saída inclui:
ML-KEM
ML-KEM-1024
ML-KEM-512
ML-KEM-768
ML-DSA
ML-DSA-44
ML-DSA-65
ML-DSA-87
A consulta através de Security.getAlgorithms() permite verificar diretamente os algoritmos registados para cada tipo de serviço criptográfico. O serviço KEM apresenta as variantes de ML-KEM e o serviço Signature as variantes de ML-DSA disponíveis na JVM.
> ML-KEM
O ML-KEM é um mecanismo de encapsulamento de chaves baseado em reticulados de módulos, normalizado pelo NIST através do FIPS 203.
A norma define três conjuntos de parâmetros:
ML-KEM-512
ML-KEM-768
ML-KEM-1024
Cada conjunto estabelece parâmetros criptográficos distintos e corresponde a um nível de segurança diferente, com impacto também na dimensão das chaves, na mensagem de encapsulamento e no custo computacional das operações.
O funcionamento do ML-KEM assenta num par constituído por uma chave pública de encapsulamento e uma chave privada de decapsulamento. A parte que pretende estabelecer um segredo utiliza a chave pública do destinatário para produzir simultaneamente um segredo partilhado e uma mensagem de encapsulamento.
A mensagem de encapsulamento é enviada ao destinatário, que utiliza a chave privada correspondente para obter o mesmo segredo partilhado. O segredo propriamente dito não é transmitido através da comunicação.
No Java, estas operações são disponibilizadas através do serviço KEM, enquanto a geração e reconstrução das chaves utiliza KeyPairGenerator e KeyFactory, mantendo o modelo normal da JCA.
Entre as três variantes, ML-KEM-768 assume particular relevância no JDK 27 por ser a componente pós-quântica utilizada no grupo híbrido X25519MLKEM768, ativado por omissão no SunJSSE.
> ML-DSA
O ML-DSA é um algoritmo de assinatura digital baseado em reticulados de módulos, normalizado pelo NIST através do FIPS 204.
O Java disponibiliza os três conjuntos de parâmetros definidos pela norma:
ML-DSA-44
ML-DSA-65
ML-DSA-87
Cada conjunto estabelece um compromisso diferente entre nível de segurança, dimensão das chaves, tamanho das assinaturas e desempenho das operações.
A integração no Java é feita através do serviço Signature da JCA. As aplicações utilizam o mesmo modelo já existente para outros algoritmos de assinatura: a chave privada produz a assinatura e a chave pública correspondente permite verificá-la.
As chaves são tratadas através de KeyPairGenerator e KeyFactory, enquanto as operações de assinatura e verificação utilizam Signature.
ML-DSA passa assim a integrar o mesmo modelo de providers e serviços criptográficos utilizado pelo restante ecossistema Java, permitindo incorporar assinaturas pós-quânticas sem introduzir uma arquitetura paralela.
> TLS
A principal evolução introduzida pelo JDK 27 encontra-se no Java Secure Socket Extension.
O SunJSSE passa a suportar três grupos híbridos para a troca de chaves no TLS 1.3:
X25519MLKEM768
SecP256r1MLKEM768
SecP384r1MLKEM1024
Estes grupos estão definidos na RFC 10024 e combinam ML-KEM com ECDHE.
O X25519MLKEM768 combina X25519 com ML-KEM-768. O SecP256r1MLKEM768 combina ECDHE sobre secp256r1, correspondente a NIST P-256, com ML-KEM-768. O SecP384r1MLKEM1024 combina ECDHE sobre secp384r1, correspondente a NIST P-384, com ML-KEM-1024.
Os três mecanismos são integrados no modelo de grupos nomeados utilizado pelo TLS 1.3 e são anunciados através da extensão supported_groups.
Cada identificador representa a combinação completa. Quando X25519MLKEM768 é negociado, cliente e servidor utilizam simultaneamente X25519 e ML-KEM-768 e combinam os segredos produzidos pelas duas operações.
Na configuração predefinida do JDK 27, X25519MLKEM768 encontra-se ativado. Os grupos SecP256r1MLKEM768 e SecP384r1MLKEM1024 também são implementados pelo SunJSSE, mas encontram-se desativados por omissão.
> híbrido
A troca de chaves híbrida combina dois mecanismos assentes em famílias criptográficas diferentes.
No X25519MLKEM768, uma componente utiliza X25519 e a outra utiliza ML-KEM-768.
X25519 executa uma operação ECDH sobre Curve25519 e produz um segredo partilhado a partir dos valores efémeros gerados pelo cliente e pelo servidor. ML-KEM-768 utiliza uma chave pública de encapsulamento para produzir outro segredo partilhado e a respetiva mensagem de encapsulamento.
No final das duas operações existem dois segredos independentes:
segredo ML-KEM-768
segredo X25519
Para X25519MLKEM768, a RFC 10024 define o valor combinado através da concatenação:
segredo ML-KEM-768 || segredo X25519
Cada componente possui 32 bytes, produzindo um total de 64 bytes.
Este valor é utilizado como entrada no processo de derivação de chaves do TLS 1.3, baseado em HKDF, a partir do qual são produzidos os diferentes segredos e chaves necessários durante a sessão.
De forma simplificada:
A sessão utiliza assim material criptográfico proveniente simultaneamente de uma componente clássica e de uma componente pós-quântica.
> negociação
A RFC 10024 define também a representação dos valores transportados durante a negociação TLS.
No ClientHello, o valor key_exchange correspondente a X25519MLKEM768 contém:
chave de encapsulamento ML-KEM-768 || chave pública efémera X25519
A chave de encapsulamento ML-KEM-768 ocupa 1184 bytes e a chave pública X25519 ocupa 32 bytes, produzindo um valor total de 1216 bytes.
O servidor utiliza a chave de encapsulamento ML-KEM-768 recebida para produzir o segredo pós-quântico e a respetiva mensagem de encapsulamento. Em paralelo, gera o seu valor público efémero X25519 e calcula a componente ECDH.
No ServerHello, o valor transmitido contém:
encapsulamento ML-KEM-768 || chave pública efémera X25519
O encapsulamento ML-KEM-768 ocupa 1088 bytes e o valor X25519 ocupa 32 bytes, totalizando 1120 bytes.
A seleção é realizada através do processo normal de negociação do TLS 1.3. O cliente anuncia X25519MLKEM768 entre os grupos suportados e o servidor pode selecioná-lo quando também disponibiliza esse grupo.
A configuração predefinida do SunJSSE permite assim que aplicações executadas sobre o JDK 27 negociem automaticamente X25519MLKEM768 com contrapartes compatíveis.
> configuração
A lista e a ordem de preferência dos grupos utilizados pelo SunJSSE podem ser alteradas através da propriedade jdk.tls.namedGroups.
Por exemplo, para utilizar X25519MLKEM768 como primeira preferência e manter x25519 como alternativa:
java \
-Djdk.tls.namedGroups=X25519MLKEM768,x25519 \
Aplicacao
Os grupos SecP256r1MLKEM768 e SecP384r1MLKEM1024, disponíveis mas desativados por omissão, podem ser incluídos explicitamente quando a política criptográfica ou os requisitos do ambiente justificarem a sua utilização.
A propriedade permite controlar os mecanismos aceites e a respetiva ordem de preferência sem alterar o código da aplicação, tornando-a particularmente útil em testes de interoperabilidade e durante uma introdução progressiva dos novos grupos.
> verificação
A utilização efetiva do mecanismo híbrido pode ser observada através da informação de depuração do JSSE.
A negociação TLS pode ser apresentada em detalhe através de:
java \
-Djavax.net.debug=ssl,handshake \
Aplicacao
No ClientHello, a extensão supported_groups apresenta os grupos suportados pelo cliente, enquanto key_share contém os valores enviados para iniciar a troca.
Quando o servidor seleciona o mecanismo híbrido, o ServerHello apresenta X25519MLKEM768 como grupo associado à sua key_share:
"key_share (51)": {
"server_share": {
"named group": X25519MLKEM768
...
}
}
A presença de X25519MLKEM768 no server_share confirma que aquela sessão utilizou a combinação de ML-KEM-768 com X25519.
Esta verificação permite validar diretamente o comportamento das aplicações, dos servidores e dos componentes intermédios durante a introdução da criptografia pós-quântica.
> impacto
A utilização dos novos grupos híbridos aumenta a quantidade de informação trocada durante a negociação TLS.
Uma chave pública X25519 ocupa 32 bytes. Em X25519MLKEM768, o valor enviado pelo cliente possui 1216 bytes e o valor devolvido pelo servidor possui 1120 bytes.
O aumento resulta essencialmente das estruturas ML-KEM e deve ser considerado em ambientes com restrições de largura de banda, latência elevada ou componentes intermédios que processem as mensagens TLS.
Proxies, balanceadores de carga, sistemas de inspeção e terminações TLS passam também a integrar os testes de interoperabilidade. Cada sessão estabelecida ao longo da arquitetura possui a sua própria negociação criptográfica.
Uma ligação entre um cliente e um balanceador pode utilizar X25519MLKEM768, enquanto uma segunda sessão entre o balanceador e a aplicação utiliza outro grupo. A validação da adoção deve, por isso, abranger todos os pontos onde existe terminação TLS e estabelecimento de uma nova sessão.
A integração dos mecanismos diretamente no JDK facilita este processo. As aplicações podem começar a negociar os novos grupos através do SunJSSE e os administradores conseguem observar o resultado através dos mecanismos de depuração já existentes na plataforma.
> conclusão
A integração da criptografia pós-quântica no Java tem sido progressiva e acompanha a maturação das novas normas criptográficas.
O JDK 21 introduziu a API genérica para mecanismos de encapsulamento de chaves. O JDK 24 integrou ML-KEM e ML-DSA nos providers criptográficos da Java Cryptography Architecture. O JDK 27 leva agora ML-KEM para o TLS 1.3 através de grupos híbridos de troca de chaves.
O X25519MLKEM768 assume um papel central nesta evolução. O SunJSSE disponibiliza-o por omissão, combinando o segredo produzido pelo ML-KEM-768 com o segredo obtido através de X25519 e entregando o resultado ao processo de derivação de chaves do TLS 1.3.
A integração ocorre através das interfaces já utilizadas pelas aplicações Java. ML-KEM e ML-DSA passam a fazer parte dos serviços disponibilizados pela JCA, enquanto a proteção híbrida das sessões TLS é tratada diretamente pelo JSSE.
O resultado é uma evolução importante da plataforma. Os mecanismos pós-quânticos deixam de estar limitados a bibliotecas adicionais ou ambientes de experimentação e passam a integrar as abstrações criptográficas normais do Java.
Depois do OpenSSL e do OpenSSH, também o Java coloca a criptografia pós-quântica diretamente ao alcance das aplicações e infraestruturas utilizadas diariamente.
> referencias
OpenJDK – JEP 452: Key Encapsulation Mechanism API
Introdução da API genérica para mecanismos de encapsulamento de chaves no JDK 21.
OpenJDK – JEP 496: Quantum-Resistant Module-Lattice-Based Key Encapsulation Mechanism
Integração do ML-KEM no JDK 24 através da Java Cryptography Architecture.
OpenJDK – JEP 497: Quantum-Resistant Module-Lattice-Based Digital Signature Algorithm
Integração do ML-DSA no JDK 24 através da Java Cryptography Architecture.
OpenJDK – JEP 527: Post-Quantum Hybrid Key Exchange for TLS 1.3
Introdução no JDK 27 dos grupos híbridos de troca de chaves para TLS 1.3.
Oracle – JDK Providers Documentation, Java SE 27
Documentação dos providers criptográficos do JDK 27, incluindo ML-KEM, ML-DSA e os grupos híbridos suportados pelo SunJSSE.
Oracle – Java Secure Socket Extension Reference Guide, Java SE 27
Documentação da configuração e negociação dos grupos nomeados no SunJSSE.
IETF – RFC 10024: Post-Quantum Traditional Hybrid Key Agreement Mechanisms for TLS 1.3
Especificação dos grupos X25519MLKEM768, SecP256r1MLKEM768 e SecP384r1MLKEM1024, incluindo a representação dos valores trocados e a construção dos segredos híbridos.
NIST – FIPS 203: Module-Lattice-Based Key-Encapsulation Mechanism Standard
Especificação do ML-KEM e dos conjuntos de parâmetros ML-KEM-512, ML-KEM-768 e ML-KEM-1024.
NIST – FIPS 204: Module-Lattice-Based Digital Signature Standard
Especificação do ML-DSA e dos conjuntos de parâmetros ML-DSA-44, ML-DSA-65 e ML-DSA-87.
> status: hybrid
> exit 0