Java stellt Post-Quanten-Bausteine bereit, bevor es einen Post-Quanten-TLS-Handshake bereitstellt. Für eine serverseitige Java-Anwendung hinter einem Reverse Proxy führt der schnellste Weg zum hybriden Schlüsselaustausch mit ML-KEM (Module-Lattice-Based Key Encapsulation Mechanism, standardisiert als NIST FIPS 203) über ein Upgrade des Proxys, nicht der JVM. Wenn Java der TLS-Client ist, hängt der hybride Schlüsselaustausch vom JDK-Release und vom verwendeten JSSE-Provider ab. Eine verlässliche Antwort liefern daher nur die Release Notes des tatsächlich eingesetzten Builds, bestätigt durch einen Handshake-Test.
Klären Sie zuerst, welche Seite des Handshakes Sie verantworten
Ein TLS-Schlüsselaustausch wird von den beiden Stacks ausgehandelt, die den Handshake durchführen, nicht vom Anwendungscode. Drei Fälle decken nahezu jedes Java-Deployment ab, und sie haben unterschiedliche Antworten.
- Eingehender Verkehr, der an einem Proxy terminiert wird. Ein Ingress-Controller, Load Balancer, CDN oder eine nginx-, Apache-, HAProxy- oder Caddy-Instanz führt den Handshake durch. Die JVM sieht den Schlüsselaustausch nie. Ein Upgrade des Proxys genügt, um Browsern und API-Clients hybride Gruppen anzubieten.
- Eingehender Verkehr, der in der JVM terminiert wird. Ein eingebetteter Tomcat-, Jetty-, Undertow- oder Netty-Listener mit einem Java-Keystore. Hier stammt die Gruppenliste aus der TLS-Implementierung des JDK (JSSE) oder aus der nativen TLS-Bibliothek hinter dem Connector.
- Ausgehender Verkehr, Java als Client. HTTP-Clients, die Partner-APIs aufrufen, JDBC- und Message-Broker-Treiber, Object-Storage-SDKs, Mutual TLS zwischen internen Diensten. Die Java-Seite schlägt die Liste
supported_groupsvor, und der entfernte Server wählt eine Gruppe aus.
Priorisieren Sie die Arbeit nach dem Prinzip harvest now, decrypt later (HNDL): Ein Angreifer, der heute Verkehr aufzeichnet und ihn Jahre später entschlüsselt, wird durch den Schlüsselaustausch abgewehrt, nicht durch das Zertifikat. Deshalb hat die Schlüsselvereinbarung mit ML-KEM Vorrang, und die Migration der Signaturen kann folgen. Das IANA-TLS-Registry führt die verwendeten hybriden Gruppen, darunter X25519MLKEM768 (Codepoint 0x11EC), SecP256r1MLKEM768 und SecP384r1MLKEM1024 (IANA TLS parameters), und RFC 10024 spezifiziert die hybride Schlüsselvereinbarung aus Post-Quanten- und klassischen Verfahren für TLS 1.3 (RFC 10024).
Wo das JDK heute steht
Zwei Ebenen müssen auseinandergehalten werden: die kryptografischen Primitive, die über die Java Cryptography Architecture (JCA) bereitgestellt werden, und die Unterstützung hybrider Gruppen innerhalb von JSSE.
Primitive: in aktuellen Releases verfügbar
JEP 452 hat in JDK 21 eine API für Key Encapsulation Mechanisms (KEM) eingeführt, javax.crypto.KEM. JDK 24 hat Implementierungen von ML-KEM (JEP 496) und von ML-DSA (Module-Lattice-Based Digital Signature Algorithm, NIST FIPS 204) in JEP 497 ergänzt, erreichbar über die üblichen APIs KeyPairGenerator, KEM und Signature mit Algorithmusnamen für jeden Parametersatz. Da JDK-Funktionen in Folgereleases erhalten bleiben, sind sie auch in späteren Releases enthalten. Das benötigen Sie für eigene Protokolle, Key Wrapping, Token-Formate und Test-Harnesses. Für sich genommen ist das jedoch noch kein TLS.
Hybride TLS-Gruppen: Lesen Sie die Release Notes Ihres JDK
Eine hybride Gruppe in einem TLS-1.3-Handshake anzubieten, ist eine eigenständige Aufgabe innerhalb von JSSE: Die Gruppe muss registriert, Key Shares müssen erzeugt und geparst und das gemeinsame Geheimnis aus beiden Komponenten abgeleitet werden. Ob das von Ihnen eingesetzte JDK dies leistet, unter welchen Gruppennamen und ob es standardmäßig aktiviert ist, unterscheidet sich je nach Release und Hersteller-Build, da Distributionen selektiv zurückportieren. Schließen Sie nicht aus dem Vorhandensein von ML-KEM in der JCA auf TLS-Unterstützung, und verlassen Sie sich nicht auf einen Artikel über einen anderen Build. Prüfen Sie die Release Notes Ihrer exakten JDK-Version und verifizieren Sie dann empirisch mit dem unten beschriebenen Handshake-Test.
| Ebene | Was zu prüfen ist | Wo Sie nachsehen |
|---|---|---|
| JCA-Primitive | Schlüsselpaarerzeugung, Kapselung und Signaturprüfung mit ML-KEM und ML-DSA | JDK-Release-Notes, Dokumentation der Standard-Algorithmusnamen |
| Hybride JSSE-Gruppen | Ob die hybride Gruppe im ClientHello oder ServerHello erscheint | JDK-Release-Notes sowie ein echter Handshake mit Debug-Logging |
| Natives TLS hinter einem Connector | Version der vom Connector genutzten nativen Bibliothek (ML-KEM-Gruppen erfordern in OpenSSL-Builds OpenSSL 3.5 oder neuer) | Abhängigkeitsbaum, Version der nativen Bibliothek zur Laufzeit |
| Proxy oder Ingress | Gruppenliste und Reihenfolge, klassischer Fallback weiterhin vorhanden | Proxy-Konfiguration und deren eigene Release Notes |
Ihre Optionen, nach Aufwand geordnet
Eingehendes TLS an einem Proxy terminieren
Das ist der pragmatische Standardweg für serverseitiges Java. Der Proxy benötigt eine TLS-Bibliothek, die die ML-KEM-Gruppen implementiert: In OpenSSL-Builds bedeutet das OpenSSL 3.5 oder neuer. Konfigurieren Sie die hybride Gruppe an erster Stelle und behalten Sie klassische Gruppen dahinter bei, damit Clients ohne Hybrid-Unterstützung weiterhin eine Verbindung aufbauen können, und validieren Sie in Staging, bevor Sie in Produktion gehen. Die schrittweisen Direktiven für die gängigen Server finden Sie in unserem Leitfaden zur Aktivierung von ML-KEM auf nginx, Apache, HAProxy und Caddy. Ein praktischer Hinweis: Ein hybrider Key Share ist deutlich größer als ein X25519-Key-Share, wodurch das ClientHello Paketgrenzen überschreiten kann. Alte Middleboxes und fehlerhaft arbeitende Netzwerkgeräte gehen damit mitunter falsch um. Testen Sie daher aus den Netzen, die Ihre Clients tatsächlich nutzen.
Das JDK dort aktualisieren, wo die JVM TLS terminiert
Wenn ein Java-Listener direkt mit Clients kommuniziert oder wenn Java in einer für Sie relevanten Verbindung der Client ist, besteht die saubere Lösung darin, ein JDK-Release einzusetzen, dessen JSSE die hybride Gruppe anbietet, und dies anschließend auf der Leitung zu bestätigen. JSSE stellt die dokumentierte Systemeigenschaft jdk.tls.namedGroups bereit, um die angebotenen Gruppen einzuschränken und zu ordnen. Welche Namen akzeptiert werden, hängt vom Release ab. Übernehmen Sie sie daher aus Ihren Release Notes, statt ein Beispiel zu kopieren, und belassen Sie stets eine klassische Gruppe wie X25519 in der Liste. Legen Sie sich in Produktion nicht auf eine einzige Post-Quanten-Gruppe fest.
Eine Provider-Bibliothek ergänzen oder ausgehenden Verkehr über ein Gateway leiten
Ein JCA- oder JSSE-Provider eines Drittanbieters kann Algorithmen und in manchen Fällen einen vom JDK unabhängigen TLS-Stack bereitstellen. Wägen Sie das sorgfältig ab: Die Installation eines Providers ändert das Sicherheitsverhalten der gesamten JVM, sie wirkt sich auf den FIPS-Modus und auf die Validierung von Zertifikatspfaden aus, und sie wird zu einer Abhängigkeit, die Sie patchen müssen. Begrenzen Sie die Änderung auf den SSLContext des jeweiligen Clients, sofern die Bibliothek dies zulässt, statt die globale Provider-Reihenfolge zu ändern. Für ausgehende Aufrufe aus Legacy-JVMs, die nicht aktualisiert werden können, ist ein Egress-Proxy, der den Handshake durchführt, oft einfacher und leichter zu auditieren, als jede Anwendung zu ändern. Beachten Sie außerdem, dass Connectors mit einer nativen TLS-Bibliothek (zum Beispiel Netty mit netty-tcnative) der Version dieser Bibliothek folgen, nicht dem JDK.
Inventarisieren Sie die Kryptografie-Nutzung in Java, bevor Sie etwas ändern
Jeder offizielle Zeitplan beginnt mit der Bestandsaufnahme, und Auditoren fragen nach dem Inventar, bevor sie nach der Migration fragen. Diese rein lesenden Befehle liefern einen ersten Durchgang; passen Sie die Pfade an Ihre Build-Struktur an.
# 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"
Erfassen Sie mehr als nur TLS. Java-Anwendungen signieren auch JSON Web Tokens und SAML-Assertions, prüfen signierte JARs, verschlüsseln Datenbankspalten und pinnen Vertrauensanker. Halten Sie die quantenverwundbaren Public-Key-Algorithmen fest (RSA, ECDSA, EdDSA, ECDH, Diffie-Hellman über endlichen Körpern und DSA sind unabhängig von der Schlüssellänge alle vom Shor-Algorithmus betroffen), wo jeder davon eingesetzt wird, wer dafür verantwortlich ist und ob der Algorithmus ohne Codeänderung konfigurierbar ist. Eine maschinenlesbare Cryptography Bill of Materials ist ein praktikabler Weg, diese Liste aktuell zu halten: siehe was ein CBOM ist und wie Sie eines erstellen. Behalten Sie auch die Sicherheitsrichtliniendateien des JDK im Blick, denn jdk.tls.disabledAlgorithms und jdk.certpath.disabledAlgorithms in java.security bestimmen bereits, was Ihre JVMs akzeptieren.
Testen Sie, was der Handshake tatsächlich aushandelt
Aussagen über Unterstützung sind ohne eine ausgehandelte Gruppe wertlos. Führen Sie drei Prüfungen in dieser Reihenfolge durch.
# 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"
Schritt 3 ist für Java als Client entscheidend: Die Debug-Ausgabe zeigt die Gruppen im ClientHello und die für den Schlüsselaustausch gewählte Gruppe. Erscheint die hybride Gruppe nie, bietet der JDK-Build sie nicht an, unabhängig davon, was die Dokumentation nahelegte. Bewahren Sie die Ausgabe zusammen mit dem JDK-Versionsstring und dem Datum als Nachweis auf. Unser kostenloser Scanner deckt Schritt 1 von außen ab, einschließlich TLS-Versionen, Cipher Suites und Zertifikatskette; was ein Ergebnis bedeutet und was nicht, beschreibt unsere Methodik-Seite.
Wie sich das in Audits niederschlägt
Das soeben erstellte Inventar ist das Artefakt, das die meisten Regelwerke verlangen. Die folgenden Angaben dienen der Information und stellen keine Rechtsberatung dar. Anforderung 12.3.3 von PCI DSS v4.0.1, seit dem 31. März 2025 verpflichtend, verlangt ein dokumentiertes Inventar der eingesetzten Cipher Suites und Protokolle, das mindestens alle 12 Monate überprüft wird, mit einer Strategie für erwartete Veränderungen bei kryptografischen Schwachstellen: siehe unsere Seite zu PCI-DSS-Anforderung 12.3.3. Im Rahmen von DORA verlangt Art. 6 der Delegierten Verordnung (EU) 2024/1774 der Kommission eine Richtlinie für Verschlüsselung und kryptografische Kontrollen mit Bestimmungen zur Aktualisierung oder Änderung kryptografischer Technologie entsprechend den Entwicklungen in der Kryptoanalyse, und Art. 7 verlangt ein Schlüsselmanagement sowie ein Register der Zertifikate für IKT-Assets, die kritische oder wichtige Funktionen unterstützen (EUR-Lex). Interpretation, nicht Wortlaut: In einer Java-Landschaft besteht der praktische Nachweis zu Art. 6 darin, dass Ihre Dienste Gruppen und Algorithmen per Konfiguration und über ein JDK- oder Proxy-Upgrade wechseln können, nicht durch eine Neuentwicklung. Zum Status der Algorithmen: NIST hat FIPS 203, 204 und 205 am 13. August 2024 als finale Standards veröffentlicht (FIPS 203), während NIST IR 8547, das vorschlägt, Public-Key-Algorithmen mit 112-Bit-Sicherheit nach 2030 als veraltet einzustufen und quantenverwundbare Public-Key-Algorithmen nach 2035 nicht mehr zuzulassen, weiterhin ein Initial Public Draft ist (NIST IR 8547 ipd).
Der nächste konkrete Schritt
Wählen Sie einen von außen erreichbaren Java-Dienst und scannen Sie Ihre Domain mit PQC Status, um zu sehen, welche Gruppe er heute aushandelt. Lautet die Antwort ausschließlich klassisch und terminiert ein Proxy TLS, aktualisieren Sie diesen Proxy auf einen Build mit OpenSSL 3.5 oder neuer und setzen Sie die hybride Gruppe in Staging vor X25519. Terminiert die JVM TLS oder ist Java der Client in einer Verbindung, die langlebige Geheimnisse überträgt, erfassen Sie die JDK-Version in Ihrem Inventar, lesen Sie deren Release Notes zum hybriden Schlüsselaustausch und sichern Sie in jedem Fall ein Handshake-Log als Nachweis. Scannen Sie nach jeder Änderung erneut und behalten Sie den klassischen Fallback bei, bis Ihre Clients ihn nicht mehr benötigen.