Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B38FGKKam5SCGgwgduVAh3
1.9 KiB
4. Post-quantum hybrid key exchange in TLS 1.3 (JEP 527)
Prev: 3. Compact headers · Next: 5. Primitive patterns
JDK 27's default TLS 1.3 client offers the hybrid group X25519MLKEM768 first: an ordinary X25519 exchange and an ML-KEM-768 key encapsulation combined, so a recorded session stays safe even if a large quantum computer later breaks X25519.
Who negotiates what
scripts/tls-pq.sh starts a loopback TLS server with TlsPeer on one JDK and connects with a client on
the other, for all four pairings, with -Djavax.net.debug=ssl:handshake (30).
| Client | Server | Group selected |
|---|---|---|
| 26 | 26 | x25519 |
| 27 | 27 | X25519MLKEM768 |
| 27 | 26 | x25519 (the 26 server does not know the hybrid group) |
| 26 | 27 | x25519 (the 26 client never offered it) |
Nothing fails when the peers disagree: the hybrid only happens when both ends are on 27 (or another stack that supports it).
The catch: a bigger first packet
ClientHelloSize captures the first TLS record (31):
| Client | ClientHello record | Fits one TCP segment (1460-byte MSS)? |
|---|---|---|
| JDK 26 | 417 bytes | yes |
| JDK 27 | 1573 bytes | no |
JDK 27, -Djdk.tls.namedGroups=x25519,secp256r1 |
408 bytes | yes |
The ML-KEM public key alone is 1184 bytes, so the ClientHello no longer fits in one segment. Middleboxes that mishandle a ClientHello spanning segments are the known failure mode of large post-quantum ClientHellos; that failure was not observed here (loopback has no middleboxes). If you meet it, the opt-out is the system property above, and the client then behaves like 26 (32).
Prev: 3. Compact headers · Next: 5. Primitive patterns