Tekko

Language

Get in Touch →

Usually respond within 24 hours

Back to BlogSecurity

Post-Quantum TLS: Migrating to ML-KEM (Kyber) for Secure Services

6 min read
CryptographyPQCTLSBackendCybersecurity
Post-Quantum TLS: Migrating to ML-KEM (Kyber) for Secure Services

The Silent Threat: Store Now, Decipher Later (SNDL)

As engineers, we often focus on immediate threats: SQL injections, misconfigured S3 buckets, or zero-day vulnerabilities in our dependencies. However, a systemic threat is looming over our encrypted communications that requires action today, even though the 'exploit' may be years away. This is the "Store Now, Decipher Later" (SNDL) attack.

State actors and well-funded adversaries are currently intercepting and archiving massive amounts of encrypted traffic. While they cannot break the AES-256 or ChaCha20 encryption protecting the data today, they are betting on the future availability of a Cryptographically Relevant Quantum Computer (CRQC). When such a machine exists, Shor’s algorithm will render our current asymmetric primitives—RSA, Diffie-Hellman, and Elliptic Curve Diffie-Hellman (ECDH)—obsolete.

For service-to-service communication within a VPC or across the public internet, the handshake that establishes your session keys is the weak point. If you want your data to remain confidential for the next 10 to 15 years, you must transition to Post-Quantum Cryptography (PQC) now.

Understanding ML-KEM (Formerly Kyber)

In August 2024, NIST finalized the first set of PQC standards. The most significant for TLS communication is FIPS 203, which standardizes ML-KEM (Module-Lattice-Based Key-Encapsulation Mechanism), derived from the Kyber algorithm.

ML-KEM relies on the hardness of the "Module Learning with Errors" (M-LWE) problem. Unlike the integer factorization or discrete logarithm problems that underpin RSA and ECC, M-LWE is believed to be resistant to both classical and quantum attacks.

Why ML-KEM-768?

ML-KEM comes in three security strengths: 512, 768, and 1024.

  • ML-KEM-512: Roughly equivalent to AES-128 security.
  • ML-KEM-768: Equivalent to AES-192. This is the "sweet spot" for most industry applications, offering a robust balance between security margins and performance.
  • ML-KEM-1024: Equivalent to AES-256, intended for high-security government or military use where the performance overhead is a secondary concern.

The Hybrid Approach: Defense in Depth

We aren't ready to throw away Elliptic Curve Cryptography (ECC) just yet. While ML-KEM is the result of years of rigorous competition, it hasn't been battle-tested in the wild for decades like X25519.

The industry standard for migration is the Hybrid Key Exchange. In a hybrid handshake, the client and server perform two simultaneous key exchanges: one classical (e.g., X25519) and one post-quantum (e.g., ML-KEM-768). The resulting shared secrets are concatenated and fed into a Key Derivation Function (KDF).

This approach ensures that:

  1. If ML-KEM is found to have a classical vulnerability, the connection is still as secure as X25519.
  2. If a quantum computer is built, the connection is protected by ML-KEM.

Infrastructure Impact: Size and Speed

Migrating to PQC isn't a free lunch. The primary trade-off is the size of the keys and ciphertexts.

AlgorithmPublic Key SizeCiphertext Size
X2551932 bytes32 bytes
ML-KEM-7681,184 bytes1,088 bytes

An ML-KEM-768 public key is roughly 37 times larger than an X25519 key. In a TLS handshake, this means the initial ClientHello and ServerHello packets will grow significantly.

MTU and Fragmentation

One of the biggest risks in PQC migration is the Maximum Transmission Unit (MTU). A standard Ethernet frame is 1,500 bytes. A TLS handshake involving ML-KEM-768 might push the handshake packets over this limit, leading to IP fragmentation. Some middleboxes, firewalls, and older load balancers are notorious for dropping fragmented UDP/TCP packets.

Before rolling this out to production, you must validate that your network path—including ingress controllers, CDNs, and sidecars—can handle larger handshake frames.

Practical Implementation: Go and Rust

Modern languages and libraries are rapidly adopting ML-KEM. Let's look at how to enable hybrid PQC in two common backend environments.

Go (1.23+)

Go has been a pioneer in PQC adoption. As of Go 1.23, the crypto/tls package supports the X25519MLKEM768 curve (formerly X25519Kyber768Draft00).

import ( "crypto/tls" "net/http" ) func main() { config := &tls.Config{ // Go 1.23 enables this by default, but you can be explicit CurvePreferences: []tls.CurveID{ tls.X25519MLKEM768, tls.X25519, }, MinVersion: tls.VersionTLS13, } server := &http.Server{ Addr: ":443", TLSConfig: config, } server.ListenAndServeTLS("cert.pem", "key.pem") }

Rust (rustls)

If you are using rustls, the migration is similarly straightforward using the aws-lc-rs or ring providers that support PQC.

use rustls::RootCertStore; use std::sync::Arc; fn main() { // Define the hybrid key exchange group let kx_group = &[&rustls::kx_group::X25519_MLKEM768]; let mut config = rustls::ClientConfig::builder() .with_root_certificates(RootCertStore::empty()) .with_no_client_auth(); // Set the preferred key exchange groups config.kx_all_groups = kx_group.to_vec(); // Use this config for your connections... }

Migration Strategy for Service-to-Service Communication

You shouldn't flip the switch for all services at once. A staged rollout is essential to minimize the risk of connectivity outages.

Phase 1: Audit and Discovery

Identify every point where encryption is terminated. This includes:

  • External Load Balancers
  • Ingress Controllers (Nginx, Envoy, Traefik)
  • Service Mesh (Istio, Linkerd) sidecars
  • Database connections (RDS, CloudSQL)
  • Internal API clients

Phase 2: Monitoring Baseline

Establish a baseline for your handshake latency. Use tools like perf or eBPF to monitor the time spent in TLS negotiation. Pay close attention to TCP retransmission rates, which might indicate packet drops due to fragmentation.

Phase 3: The "Canary" Service

Select a non-critical internal service. Enable the hybrid X25519 + MLKEM768 key exchange on the server side first. Modern clients that don't support it will simply fall back to the classical X25519 exchange, thanks to TLS 1.3 negotiation logic.

Phase 4: Enforcing PQC

Once you have verified that the hybrid handshake is stable and performance impact is negligible, begin updating your client configurations to prefer the hybrid group.

Common Pitfalls

  1. Ignoring the Certificate Chain: While we are focusing on the Key Exchange, the Signature on the certificate is still likely RSA or ECDSA. While NIST has standardized ML-DSA (Dilithium) for signatures, the PKI infrastructure (CAs) is slower to move. For now, focus on the Key Exchange to prevent SNDL attacks.
  2. Hardware Acceleration: Most CPUs have specialized instructions for AES and ECC. ML-KEM is fast, but it doesn't yet benefit from the same level of ubiquity in hardware acceleration. Monitor CPU spikes on high-traffic gateways.
  3. Library Versions: Ensure you aren't just updating your code, but also the underlying system libraries (OpenSSL 3.4+, BoringSSL). Many language wrappers link dynamically to these.

Conclusion: Actionable Next Steps

Post-Quantum Cryptography is no longer a theoretical branch of mathematics; it is a production reality. To future-proof your infrastructure against the threat of quantum-enabled decryption, you should:

  1. Inventory your TLS stacks: Identify which services use Go 1.23+, Rustls, or OpenSSL 3.4.
  2. Test for MTU issues: Simulate larger TLS handshakes in your staging environment to ensure your network gear doesn't choke on fragmented packets.
  3. Enable Hybrid Key Exchange: Configure your internal services to support X25519MLKEM768.

By implementing hybrid PQC today, you ensure that the data your services exchange remains confidential not just for the duration of the session, but for the decades to come.