Migrating to ML-KEM: A Guide to Post-Quantum TLS Handshakes
The cryptographic foundations of the internet are facing a generational shift. For decades, we have relied on RSA and Elliptic Curve Cryptography (ECC) to secure our service-to-service communications. However, the progress of quantum computing has introduced a definitive expiration date for these algorithms. While a cryptographically relevant quantum computer (CRQC) doesn't exist yet, the threat is already active in the form of 'Harvest Now, Decrypt Later' (HNDL) attacks.
In an HNDL scenario, adversaries capture and store encrypted traffic today, waiting for the day a quantum computer can break the underlying asymmetric keys. For long-lived data or high-stakes service-to-service communication, the time to migrate is now. This article explores the transition to Post-Quantum Cryptography (PQC), focusing on ML-KEM (formerly known as Kyber) and how to implement it within your TLS infrastructure.
The Shift from Diffie-Hellman to ML-KEM
Traditional key exchanges like Elliptic Curve Diffie-Hellman (ECDH) rely on the hardness of the discrete logarithm problem. Shor’s algorithm proves that a sufficiently powerful quantum computer can solve this problem efficiently. To counter this, NIST has standardized a new class of algorithms based on lattice-based cryptography, specifically Module-Lattice-Based Key-Encapsulation Mechanism (ML-KEM).
ML-KEM (standardized as FIPS 203) is the primary algorithm chosen for general-purpose encryption. Unlike Diffie-Hellman, which is a key exchange protocol where both parties contribute to a shared secret, ML-KEM is a Key Encapsulation Mechanism (KEM). In a KEM flow:
- The recipient generates a key pair and sends the public key to the sender.
- The sender uses the public key to 'encapsulate' a shared secret, producing a ciphertext.
- The sender sends the ciphertext back to the recipient.
- The recipient 'decapsulates' the ciphertext using their private key to recover the shared secret.
For TLS 1.3, this change is largely transparent to the application layer, but it significantly alters the handshake's byte structure and computational profile.
Why Hybrid Key Exchange is the Gold Standard
We are currently in a transition period. While ML-KEM is mathematically robust against quantum attacks, it hasn't survived decades of real-world 'battle-testing' like X25519. There is also the risk of implementation bugs in new cryptographic libraries.
To mitigate these risks, the industry has converged on Hybrid Key Exchange. A hybrid approach combines a classical algorithm (like X25519) with a post-quantum algorithm (like ML-KEM-768). The resulting shared secret is a combination of both. To break the connection, an attacker would need to break both the classical and the quantum-resistant algorithm.
The most common construction used today—and the one supported by Chrome, Cloudflare, and AWS—is X25519MLKEM768. This combines the speed and reliability of X25519 with the quantum-resistance of ML-KEM-768.
Implementing ML-KEM in Service-to-Service Communication
When securing internal traffic (e.g., between a Go-based microservice and a Rust-based data store), the implementation details depend heavily on your language's TLS library.
1. Go (Golang) Implementation
As of Go 1.24, the crypto/tls package has introduced support for ML-KEM. If you are using an older version, you might need to use the cloudfare/circl library, but for modern stacks, the native implementation is preferred.
// Example: Configuring a TLS Client with Hybrid PQC config := &tls.Config{ CurvePreferences: []tls.CurveID{ tls.X25519MLKEM768, // Primary choice tls.CurveP256, tls.X25519, }, MinVersion: tls.VersionTLS13, } client := &http.Client{ Transport: &http.Transport{ TLSClientConfig: config, }, }
On the server side, ensuring your tls.Config includes X25519MLKEM768 in the CurvePreferences will allow the server to negotiate the hybrid exchange if the client supports it.
2. Rust Implementation with Rustls
Rustls, the modern alternative to OpenSSL in the Rust ecosystem, is at the forefront of PQC adoption. Using the aws-lc-rs crypto provider (which is FIPS-compliant and high-performance), you can enable ML-KEM easily.
// Example: Rustls configuration for ML-KEM let provider = rustls::crypto::aws_lc_rs::default_provider(); let mut config = rustls::ClientConfig::builder_with_provider(provider.into()) .with_safe_default_protocol_versions()? .with_root_certificates(root_store) .with_no_client_auth(); // aws-lc-rs includes X25519MLKEM768 in its default suites in recent versions
Infrastructure and Performance Considerations
Migrating to PQC isn't just a code change; it has operational implications that senior engineers must account for.
Handshake Size and MTU
Classical ECDH public keys are tiny (around 32 bytes for X25519). ML-KEM-768 public keys are significantly larger (roughly 1,184 bytes), and the encapsulated ciphertext is approximately 1,088 bytes.
This means the TLS ClientHello and ServerHello messages will no longer fit in a single TCP packet if you are also carrying large certificate chains or session tickets. This can lead to IP fragmentation. If your network infrastructure (firewalls, load balancers) is configured to drop fragmented packets, your TLS handshakes will fail. Before a full rollout, test your network's handling of larger handshake packets.
CPU Overhead
Surprisingly, ML-KEM is extremely efficient. In many benchmarks, ML-KEM-768 is faster than Elliptic Curve implementations in terms of CPU cycles for key generation and encapsulation. While the data transmission takes longer due to size, the computational burden on your sidecars or API gateways is unlikely to be the bottleneck.
Observability
Update your telemetry to track which key exchange algorithms are being negotiated. If you see a high fallback rate to X25519 (classical), it indicates that either your client or server isn't correctly configured for PQC, or an intermediary is stripping the new extensions.
The Migration Roadmap
For a senior engineer leading this transition, I recommend a three-phased approach:
Phase 1: Inventory and Audit
Identify every point where TLS is terminated. This includes:
- Ingress controllers (Nginx, Envoy, Traefik)
- Service-to-service links (gRPC, internal REST)
- Database connections (PostgreSQL/MySQL over TLS)
- External API integrations
Phase 2: The Hybrid Pilot
Enable X25519MLKEM768 on a non-critical internal service. Use this to validate that your monitoring tools, load balancers, and logging infrastructure can handle the new CurveID and the larger packet sizes.
Phase 3: Default-On Policy
Once the pilot is successful, update your base container images or shared networking libraries to prioritize hybrid PQC. In TLS 1.3, if a client offers ML-KEM and the server doesn't support it, they will automatically fall back to a classical algorithm, providing a safe migration path.
Potential Pitfalls
- Middleboxes: Some older 'Deep Packet Inspection' (DPI) appliances or legacy firewalls might flag the larger
ClientHelloor the unknownNamedGroupID for ML-KEM as an anomaly and drop the connection. - Dependency Lag: Ensure your underlying crypto libraries (like OpenSSL 3.2+ or BoringSSL) are up to date. Using an outdated version of a language runtime (e.g., Go 1.21) will prevent you from using native PQC features.
- Certificate Authorities: Note that we are discussing the key exchange, not the digital signatures (certificates). Migrating certificates to ML-DSA (Dilithium) is a separate, more complex challenge because it involves the entire PKI ecosystem. Focusing on the key exchange first addresses the HNDL threat effectively.
Conclusion
Post-quantum cryptography is no longer a theoretical concern for academic researchers; it is a practical requirement for modern infrastructure. By implementing hybrid ML-KEM (Kyber) today, you protect your organization’s data against future decryption while maintaining the proven security of classical algorithms.
Actionable Steps:
- Audit your runtimes: Ensure you are on Go 1.24+, OpenSSL 3.2+, or using a PQC-ready library like
aws-lc-rs. - Enable Hybrid Exchange: Configure your TLS settings to prefer
X25519MLKEM768. - Monitor MTU/Fragmentation: Watch for increased handshake failures in environments with strict network filtering.
The transition to PQC is a marathon, not a sprint, but the 'Harvest Now, Decrypt Later' threat means that the data you send today is already at risk. Start your migration with the key exchange—it is the most impactful move you can make for long-term data sovereignty.