O Java oferece blocos de construção pós-quânticos antes de oferecer um handshake TLS pós-quântico. Para uma aplicação Java no servidor atrás de um proxy reverso, o caminho mais rápido para a troca de chaves híbrida com ML-KEM (Module-Lattice-Based Key Encapsulation Mechanism, padronizado como NIST FIPS 203) é atualizar o proxy, não a JVM. Quando o Java atua como cliente TLS, a troca de chaves híbrida depende da versão do JDK e do provedor JSSE em uso; por isso, a única resposta confiável vem das notas de versão do build que você realmente implanta, confirmada por um teste de handshake.
Primeiro, defina de qual lado do handshake você é responsável
Uma troca de chaves TLS é negociada pelas duas pilhas que realizam o handshake, não pelo código da aplicação. Três casos cobrem quase todas as implantações Java, e cada um tem uma resposta diferente.
- Tráfego de entrada terminado por um proxy. Um ingress controller, load balancer, CDN ou uma instância de nginx, Apache, HAProxy ou Caddy realiza o handshake. A JVM nunca vê a troca de chaves. Atualizar o proxy basta para oferecer grupos híbridos a navegadores e clientes de API.
- Tráfego de entrada terminado pela JVM. Um listener embarcado Tomcat, Jetty, Undertow ou Netty com um keystore Java. Nesse caso, a lista de grupos vem da implementação TLS do JDK (JSSE) ou da biblioteca TLS nativa por trás do conector.
- Tráfego de saída, com o Java como cliente. Clientes HTTP que chamam APIs de parceiros, drivers JDBC e de message brokers, SDKs de armazenamento de objetos, TLS mútuo entre serviços internos. O lado Java propõe a lista
supported_groupse o servidor remoto escolhe um grupo.
Priorize o trabalho com base no risco de coleta agora, decifração depois (harvest now, decrypt later, HNDL): um atacante que grava o tráfego hoje e o decifra anos depois é neutralizado pela troca de chaves, não pelo certificado. É por isso que o estabelecimento de chaves com ML-KEM vem primeiro e a migração de assinaturas pode vir depois. O registro TLS da IANA lista os grupos híbridos em uso, incluindo X25519MLKEM768 (codepoint 0x11EC), SecP256r1MLKEM768 e SecP384r1MLKEM1024 (IANA TLS parameters), e a RFC 10024 especifica o acordo de chaves híbrido pós-quântico e tradicional para TLS 1.3 (RFC 10024).
Onde o JDK está hoje
É preciso separar duas camadas: as primitivas criptográficas expostas pela Java Cryptography Architecture (JCA) e o suporte a grupos híbridos dentro da JSSE.
Primitivas: disponíveis nas versões atuais
A JEP 452 adicionou uma API de Key Encapsulation Mechanism (KEM), javax.crypto.KEM, no JDK 21. O JDK 24 adicionou implementações de ML-KEM (JEP 496) e de ML-DSA (Module-Lattice-Based Digital Signature Algorithm, NIST FIPS 204) na JEP 497, acessíveis pelas APIs habituais KeyPairGenerator, KEM e Signature, com nomes de algoritmo para cada conjunto de parâmetros. Como os recursos do JDK são mantidos nas versões seguintes, as versões posteriores os incluem. É disso que você precisa para seus próprios protocolos, encapsulamento de chaves, formatos de token e ambientes de teste. Isso, por si só, não é TLS.
Grupos TLS híbridos: leia as notas de versão do seu JDK
Oferecer um grupo híbrido em um handshake TLS 1.3 é um trabalho separado dentro da JSSE: o grupo precisa ser registrado, os key shares precisam ser gerados e interpretados, e o segredo compartilhado precisa ser derivado dos dois componentes. Se o JDK que você executa faz isso, com quais nomes de grupo e se o recurso vem habilitado por padrão, são pontos que variam conforme a versão e o build do fornecedor, já que as distribuições fazem backports seletivos. Não deduza o suporte TLS a partir da presença do ML-KEM na JCA, e não se baseie em um artigo escrito sobre outro build. Consulte as notas de versão da sua versão exata do JDK e depois verifique empiricamente com o teste de handshake abaixo.
| Camada | O que verificar | Onde procurar |
|---|---|---|
| Primitivas JCA | Geração de pares de chaves ML-KEM e ML-DSA, encapsulamento, verificação de assinatura | Notas de versão do JDK, documentação dos nomes de algoritmo padrão |
| Grupos híbridos JSSE | Se o grupo híbrido aparece no ClientHello ou no ServerHello | Notas de versão do JDK, além de um handshake real com log de depuração |
| TLS nativo por trás de um conector | Versão da biblioteca nativa usada pelo conector (os grupos ML-KEM exigem OpenSSL 3.5 ou posterior em builds OpenSSL) | Árvore de dependências, versão da biblioteca nativa em tempo de execução |
| Proxy ou ingress | Lista e ordem dos grupos, fallback clássico ainda presente | Configuração do proxy e as notas de versão dele |
Suas opções, em ordem de esforço
Terminar o TLS de entrada em um proxy
Esse é o padrão pragmático para Java no servidor. O proxy precisa de uma biblioteca TLS que implemente os grupos ML-KEM: em builds OpenSSL, isso significa OpenSSL 3.5 ou posterior. Configure o grupo híbrido em primeiro lugar e mantenha os grupos clássicos depois dele, para que clientes sem suporte híbrido continuem se conectando, e valide em homologação antes da produção. As diretivas passo a passo para os servidores mais comuns estão no nosso guia para habilitar ML-KEM no nginx, Apache, HAProxy e Caddy. Uma ressalva prática: um key share híbrido é bem maior que um key share X25519, o que pode fazer o ClientHello ultrapassar os limites de um pacote. Middleboxes antigos e equipamentos de rede com comportamento inadequado às vezes lidam mal com isso, então teste a partir das redes que seus clientes realmente usam.
Atualizar o JDK onde a JVM termina o TLS
Se um listener Java atende clientes diretamente, ou se o Java é o cliente em uma conexão que importa para você, a correção limpa é executar uma versão do JDK cuja JSSE ofereça o grupo híbrido e depois confirmar isso no tráfego real. A JSSE expõe a propriedade de sistema documentada jdk.tls.namedGroups para restringir e ordenar os grupos que oferece. Os nomes aceitos dependem da versão, então copie-os das suas notas de versão e não de um exemplo, e sempre mantenha na lista um grupo clássico como X25519. Não fixe um único grupo pós-quântico em produção.
Adicionar uma biblioteca provedora ou rotear o tráfego de saída por um gateway
Um provedor JCA ou JSSE de terceiros pode fornecer algoritmos e, em alguns casos, uma pilha TLS independente do JDK. Avalie com cuidado: instalar um provedor altera o comportamento de segurança de toda a JVM, interage com o modo FIPS e com a validação do caminho de certificação, e se torna uma dependência que você precisa manter atualizada. Quando a biblioteca permitir, restrinja a mudança ao SSLContext do cliente específico, em vez de reordenar os provedores globais. Para chamadas de saída a partir de JVMs legadas que não podem ser atualizadas, um proxy de saída que realiza o handshake costuma ser mais simples e mais fácil de auditar do que modificar cada aplicação. Observe também que conectores que usam uma biblioteca TLS nativa (por exemplo, Netty com netty-tcnative) seguem a versão dessa biblioteca, não a do JDK.
Inventarie o uso de criptografia em Java antes de mudar qualquer coisa
Todo cronograma oficial começa pela descoberta, e os auditores pedem o inventário antes de pedir a migração. Estes comandos somente leitura dão uma primeira visão; adapte os caminhos à estrutura do seu build.
# TLS and crypto entry points in application code
grep -rnE "SSLContext|SSLSocketFactory|HttpsURLConnection|TrustManager|KeyManagerFactory" --include="*.java" src/
# algorithm names and keystore formats hard coded in source or configuration
grep -rnE "RSA|ECDSA|SHA1|MD5|PKCS12|JKS" --include="*.java" --include="*.properties" --include="*.yml" .
# which TLS stack each service really uses
mvn -q dependency:tree | grep -Ei "netty|tcnative|conscrypt|bouncycastle|okhttp|httpclient"
./gradlew dependencies --configuration runtimeClasspath | grep -Ei "netty|tcnative|okhttp|httpclient"
# keys and certificates in a keystore, with their algorithms
keytool -list -v -keystore keystore.p12 -storetype PKCS12 | grep -E "Alias name|Signature algorithm name|Subject Public Key Algorithm"
Registre mais do que o TLS. Aplicações Java também assinam JSON Web Tokens e asserções SAML, verificam JARs assinados, criptografam colunas de banco de dados e fixam âncoras de confiança. Anote os algoritmos de chave pública vulneráveis à computação quântica (RSA, ECDSA, EdDSA, ECDH, Diffie-Hellman em corpo finito e DSA são todos afetados pelo algoritmo de Shor, qualquer que seja o tamanho da chave), onde cada um é usado, quem é o responsável e se o algoritmo pode ser configurado sem alteração de código. Uma lista de materiais criptográficos legível por máquina é uma forma prática de manter essa lista atualizada: veja o que é um CBOM e como produzi-lo. Fique atento também aos arquivos de política de segurança do JDK, pois jdk.tls.disabledAlgorithms e jdk.certpath.disabledAlgorithms em java.security já determinam o que suas JVMs aceitam.
Teste o que o handshake realmente negocia
Alegações de suporte não valem nada sem um grupo negociado. Execute três verificações, nesta ordem.
# 1. external view of the listener (OpenSSL 3.5 or later on the client side)
openssl s_client -connect api.example.com:443 -groups X25519MLKEM768 </dev/null 2>&1 | grep -i "Negotiated TLS1.3 group"
# 2. the classical fallback must still work
openssl s_client -connect api.example.com:443 -groups X25519 </dev/null 2>&1 | grep -i "Negotiated TLS1.3 group"
# 3. what the Java client offers, and what the peer selects
java -Djavax.net.debug=ssl:handshake -jar client.jar 2>&1 | grep -iE "supported_groups|named group|key_share"
A etapa 3 é a decisiva para o Java como cliente: a saída de depuração mostra os grupos no ClientHello e o grupo escolhido para a troca de chaves. Se o grupo híbrido nunca aparece, o build do JDK não o oferece, independentemente do que a documentação sugeria. Guarde a saída como evidência, com a string de versão do JDK e a data. Nosso scanner gratuito cobre a etapa 1 pelo lado externo, incluindo versões de TLS, cipher suites e a cadeia de certificados; o que um resultado significa e o que ele não significa está descrito na nossa página de metodologia.
Como isso aparece nas auditorias
O inventário que você acabou de montar é o artefato que a maioria dos frameworks exige, e o que segue é informação, não aconselhamento jurídico. O requisito 12.3.3 do PCI DSS v4.0.1, obrigatório desde 31 de março de 2025, exige um inventário documentado das cipher suites e dos protocolos em uso, revisado pelo menos a cada 12 meses, com uma estratégia para mudanças previstas nas vulnerabilidades criptográficas: veja nossa página sobre o requisito 12.3.3 do PCI DSS. No âmbito do DORA, o Commission Delegated Regulation (EU) 2024/1774 Art. 6 exige uma política de criptografia e de controles criptográficos com disposições para atualizar ou substituir a tecnologia criptográfica à medida que a criptoanálise evolui, e o Art. 7 exige gestão de chaves e um registro dos certificados dos ativos de TIC que suportam funções críticas ou importantes (EUR-Lex). Interpretação, não texto legal: em um parque Java, a prova prática do Art. 6 é que seus serviços conseguem trocar grupos e algoritmos por configuração e por uma atualização do JDK ou do proxy, não por uma reescrita. Quanto ao status dos algoritmos, o NIST publicou os FIPS 203, 204 e 205 como padrões finais em 13 de agosto de 2024 (FIPS 203), enquanto o NIST IR 8547, que propõe descontinuar os algoritmos de chave pública com segurança de 112 bits após 2030 e proibir os algoritmos de chave pública vulneráveis à computação quântica após 2035, continua sendo um rascunho público inicial (NIST IR 8547 ipd).
O próximo passo concreto
Escolha um serviço Java acessível externamente e analise seu domínio com o PQC Status para ver qual grupo ele negocia hoje. Se a resposta for apenas clássico e um proxy terminar o TLS, atualize esse proxy para um build com OpenSSL 3.5 ou posterior e coloque o grupo híbrido antes do X25519 em homologação. Se a JVM terminar o TLS, ou se o Java for o cliente em uma conexão que transporta segredos de longa duração, registre a versão do JDK no seu inventário, leia as notas de versão dela sobre troca de chaves híbrida e capture um log de handshake como evidência, qualquer que seja o resultado. Faça uma nova análise após cada mudança e mantenha o fallback clássico até que seus clientes não precisem mais dele.