Post-Quantum TLS Migration: A Practitioner's Guide
"Migrate to post-quantum cryptography" is said as if it were a single switch. For TLS it isn't — it's a sequence of concrete, wire-level steps with different owners and very different difficulty. The cryptography is the easy part; NIST finished it. The hard part is everything between you and the bytes. This is the path, in order.
Why the deadline is now, even though the computers aren't
The threat is "harvest now, decrypt later": an adversary records your encrypted TLS traffic today and decrypts it once a cryptographically relevant quantum computer exists. Anything with a confidentiality lifetime beyond that horizon — health records, financial data, classified material, long-lived secrets — is already exposed, today, regardless of when the machine actually arrives.
What's broken is specific: the asymmetric key exchange. TLS establishes a shared secret with ECDH (or RSA); Shor's algorithm solves both. The symmetric cipher that encrypts the bulk data — AES-GCM, ChaCha20 — is only weakened by Grover, and a larger key restores the margin. So "post-quantum TLS" is, precisely, replacing the key exchange. Not the whole stack.
The mandates, and what each actually demands
They get blurred into one "PQC deadline." They're three documents with three different asks:
• NSM-10 (May 2022) — the national directive: move national security systems to quantum-resistant cryptography, set the machinery in motion.
• OMB M-23-02 (November 2022) — the near-term, testable ask: inventory your cryptographic systems and report it. Not deploy — inventory. What that actually requires, decoded to the wire.
• CNSA 2.0 — the schedule: which algorithms (ML-KEM for key establishment, ML-DSA for signatures) and the 2035 deadline for full NSS transition.
Underneath them, NIST finalized ML-KEM as FIPS 203 in 2024. The algorithm question is settled; what remains is rollout. The practical read: inventory is due now, replacement runs to 2035. Private-sector and international timelines differ, but the harvest-now logic and the algorithm choices are the same everywhere.
What post-quantum TLS looks like on the wire
The deployed answer today is a hybrid key exchange: X25519MLKEM768 — classical X25519 and ML-KEM-768 run together, the shared secret derived from both (draft-ietf-tls-ecdhe-mlkem; ML-KEM is FIPS 203). Byte by byte, here is what it looks like.
Hybrid, not pure ML-KEM, and on purpose: during the transition you want to be no weaker than X25519 even if a flaw turns up in the new KEM. You're protected if either holds. It carries a cost, though — the ML-KEM key share is about 1.2 KB, which pushes the ClientHello past size assumptions some middleboxes and load balancers were built on. That is a real source of breakage, not a footnote. And the codepoint, 0x11ec, is the kind of detail where a one-character slip silently disables the whole thing — we have the scar to prove it.
Step 1 — Inventory: you can't migrate what you can't see
The first deliverable, and the one most teams get wrong. The negotiated key exchange is chosen per handshake, at runtime, from what both ends offer. It is not what your config file says: libraries default differently across versions, middleboxes rewrite handshakes, and third-party callouts and shadow IT never appear in any config you own.
So an inventory built from asset spreadsheets is wrong on day one — it records intent, not the bytes that crossed the wire. The only authoritative source is the handshake itself: observed on the wire, classified into quantum-vulnerable versus hybrid, per service. Everything downstream depends on getting this right.
Step 2 — Migrate: two paths, set by who owns the endpoint
Where you control both endpoints, upgrade them. OpenSSL 3.5+, recent browsers, and the major CDNs already speak X25519MLKEM768; often it is a version bump and a config line. This is the clean path — take it everywhere you can.
Where you don't, you meet the long tail. Legacy services, vendor appliances, embedded stacks, anything you can't recompile — and the far side of every third-party call. Endpoint upgrade isn't available here, and this is where most of a real migration actually lives. The option for that tail is to upgrade the crypto in the path rather than at the endpoint: terminate and re-establish the connection so the wire carries a post-quantum handshake even when one side only knows classical crypto. Two handshakes, one connection — how that works, and the trust model it implies, are worth understanding before you reach for it.
Most real migrations are a mix: upgrade what you can, bridge what you can't. The ratio is set by how much of your estate you actually control — which is usually less than the asset inventory claims.
Step 3 — Prove it: the audit trail is the deliverable
Migration isn't done when you deploy; it's done when you can show it. The same per-handshake record that found the vulnerable crypto in Step 1 is the evidence in Step 3 — the fraction of handshakes negotiating a hybrid group, climbing toward 100%, per service, over time. That record is what satisfies the inventory obligation, and what tells you when a path is genuinely covered versus quietly falling back to classical. Detection and proof are the same instrument.
Where the hard parts actually are
Not the cryptography — that's standardized and shipping. The difficulty is operational: the systems you don't control, the 1.2 KB ClientHello breaking middleboxes, mixed-capability paths (one side post-quantum, the other not) that still have to negotiate cleanly, and proving the whole thing continuously rather than once. These are wire-level, deployment-level problems — exactly the work that never shows up in a vendor datasheet.
This is what we do. We map your real cryptographic posture from the wire, upgrade what can be upgraded, bridge what can't, and produce the continuous evidence the mandates ask for — without touching the endpoints you can't touch. If you're holding an M-23-02 inventory or a 2035 plan and trying to turn it into wire reality, that's the conversation to have.
← All posts