#!/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:

C l i e n t e M L X - 2 K 5 E 5 M 1 - 9 7 6 8 S S e e g g r r e e d d o o X M 2 L 5 - 5 K 1 E 9 M - 7 6 8 D e r i v a T ç L ã S o 1 d . e 3 S e c g h r a e v d e o s c o m b i n a d o

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