
.NET 10 shipped post-quantum cryptography in November 2025. It’s September 2026, and most .NET teams haven’t touched it. That’s a problem — not because quantum computers are breaking production systems today, but because adversaries are collecting your encrypted traffic right now, storing it, and waiting. By the time quantum hardware is ready, data transmitted years ago becomes readable. The threat is already running; only the decryption is future-dated.
This is the harvest-now, decrypt-later (HNDL) attack model, and it’s what makes the PQC migration timeline so uncomfortable. Cryptographic transitions historically take 10 to 20 years across global infrastructure. NIST started its post-quantum standardization process in 2016 and finalized FIPS 203, 204, and 205 in August 2024 — an 8-year process. .NET 10 shipped those standards as GA APIs 15 months later. If you’re waiting for “the right time” to start, you’re already behind schedule.
The Three Algorithms, Each With a Job
.NET 10 ships three post-quantum algorithms in System.Security.Cryptography. No third-party packages required. Here’s what each one does and when to reach for it.
ML-KEM (FIPS 203) replaces ECDH and Diffie-Hellman for key exchange. If two parties need to agree on a shared symmetric key, ML-KEM is how they do it in a post-quantum world. It’s the algorithm Chrome and Firefox already use for TLS key exchange on modern connections. MLKem768 is the recommended parameter set — 192-bit quantum security, balanced performance. See the official .NET PQC guide for full parameter set comparisons.
ML-DSA (FIPS 204) replaces RSA and ECDSA for digital signatures — authentication tokens, signed payloads, code signing. The catch: ML-DSA signatures run 2,420 to 4,595 bytes depending on parameter set, versus roughly 72 bytes for ECDSA. That’s a real bandwidth cost you need to plan for before rolling it out to high-frequency endpoints.
SLH-DSA (FIPS 205) is the conservative option — a hash-based signature scheme that assumes nothing except that SHA-3 holds. Signatures run from 7,856 to 49,856 bytes. Use it when you need signatures to remain valid for decades and aren’t willing to bet on lattice-based math. Skip it for high-frequency endpoints where bandwidth matters.
The Code Is Cleaner Than You Think
The PQC types don’t extend AsymmetricAlgorithm, which will break any existing code that introspects the base class. But in isolation, the API is straightforward. ML-KEM key encapsulation:
// Alice generates a keypair
using var alice = MLKem.Create(MLKemParameterSet.MLKem768);
byte[] alicePublicKey = alice.ExportPublicKey(); // 1,184 bytes
// Bob encapsulates a shared secret using Alice's public key
using var bob = MLKem.ImportPublicKey(MLKemParameterSet.MLKem768, alicePublicKey);
byte[] ciphertext;
byte[] sharedSecretBob = bob.Encapsulate(out ciphertext);
// Alice decapsulates — sharedSecretAlice == sharedSecretBob
byte[] sharedSecretAlice = alice.Decapsulate(ciphertext);
ML-DSA signing is similarly compact:
using var signer = MLDsa.Create(MLDsaParameterSet.MLDsa65);
byte[] signature = signer.SignData(message);
using var verifier = MLDsa.ImportPublicKey(MLDsaParameterSet.MLDsa65, publicKeyBytes);
bool valid = verifier.VerifyData(message, signature);
The complexity isn’t in the API. It’s in what the API doesn’t connect to yet.
What Doesn’t Work Yet
Here’s the honest part. .NET 10’s PQC support is real and production-ready at the crypto-primitive level, but the integration layer is incomplete.
No X.509 certificate binding. You can’t yet issue TLS certificates using ML-DSA keys through the standard System.Security.Cryptography.X509Certificates stack. PQC signing works at the raw-byte level; if you need it in a certificate for HTTPS, you’re building plumbing yourself or waiting for a future .NET release.
System.Net.Security isn’t PQC-aware yet. Chrome and Firefox are already doing ML-KEM key exchange in TLS 1.3. .NET’s own TLS stack isn’t there. If you’re protecting connections at the transport layer, you’re still relying on ECDH under the hood. This is tracked in the .NET GitHub runtime repo and will land — just not in .NET 10.
CompositeMLDsa is experimental. This hybrid type combines a classical signature (RSA or ECDSA) with ML-DSA so that breaking either algorithm alone doesn’t compromise the signature. It’s marked [Experimental] under SYSLIB5006. Worth tracking for transition planning, not yet production-recommended.
Where to Start This Sprint
The realistic starting point is application-layer cryptography — not TLS, not certificates. That’s where .NET 10 is ready today.
If your application builds custom key exchange protocols — secure messaging, encrypted file transfer, API token derivation — replace ECDH with ML-KEM now. The code change is small. The key size increase (1,184 bytes vs 32 bytes for an EC public key) is real, so benchmark your payloads before rolling out broadly.
If you sign payloads — JWT bodies, document hashes, API request signatures — consider adding ML-DSA alongside your existing ECDSA signature during a transition period. Dual signatures on the same payload costs bandwidth but gives you a clean cutover path once clients are updated. Check the .NET 10 library release notes for the full API surface.
If you’re starting a greenfield project in 2026, there’s no reason to default to ECDSA or ECDH for application-layer operations. PQC is the baseline for anything new.
The Clock Is Already Running
.NET is ahead of the pack here. Go added crypto/mlkem in 1.23. Java stabilized ML-KEM in JEP 496 with Java 24. Python has no stdlib PQC support. Rust has crates but nothing in std. The .NET ecosystem’s GA PQC APIs — backed by Windows CNG at the OS layer — are the most production-ready PQC story in any major enterprise runtime right now.
NSA’s CNSA 2.0 suite sets 2030 as the mandatory migration deadline for National Security Systems. That’s four years — and commercial systems should be well ahead of it, not catching up to it. .NET 10 is ready. The question is whether your codebase is.













