Why TLS Infrastructure Is the Priority for PQC Migration
TLS (Transport Layer Security) protects more sensitive data in transit than any other cryptographic protocol. Every web request, API call, email delivery, database connection, and microservice communication relies on TLS. This makes TLS infrastructure the single most impactful target for post-quantum migration.
The urgency is driven by two factors:
-
HNDL vulnerability: Every TLS session using RSA or ECDH key exchange that is intercepted today can potentially be decrypted by a future quantum computer. Migrating TLS key exchange to PQC immediately stops the accumulation of decryptable ciphertext.
-
Ecosystem readiness: Unlike many PQC migration targets, TLS hybrid key exchange is deployable today — major browsers, CDNs, and servers already support it. There are no technical blockers, only organizational inertia.
This guide provides the complete technical pathway for migrating enterprise TLS infrastructure from classical to post-quantum cryptography.
TLS PQC Migration: Two Separate Challenges
TLS uses cryptography for two distinct purposes, each requiring separate migration:
| Purpose | Current Algorithms | PQC Replacement | Deployment Status | HNDL Relevance |
|---|---|---|---|---|
| Key Exchange (confidentiality) | X25519, ECDH P-256, RSA key transport | ML-KEM-768/1024 (hybrid) | Widely deployed | Critical — directly protects against HNDL |
| Authentication (integrity) | RSA-2048/4096, ECDSA P-256/P-384 | ML-DSA-65/87 | Early stages | Lower — authentication protects against MITM, not HNDL |
Key insight: Key exchange migration provides immediate HNDL protection and is deployable today. Authentication migration (certificate algorithm change) is more complex and less urgent from an HNDL perspective. This guide addresses both but emphasizes the priority of key exchange.
Phase 1: Hybrid Key Exchange Migration
Step 1: Inventory Current TLS Configuration
Before migration, document your current state:
# Scan a server's supported key exchange groups
openssl s_client -connect example.com:443 -groups X25519:P-256:P-384 2>&1 | \
grep "Server Temp Key"
# Comprehensive TLS scan with testssl.sh
./testssl.sh --cipher-per-proto --server-defaults example.com
# Check if server already supports hybrid
openssl s_client -connect example.com:443 -groups X25519MLKEM768 2>&1 | \
grep "Server Temp Key"
QCecuring CBOM automates this inventory across your entire TLS estate — identifying every TLS termination point, the algorithms it supports, and the algorithms actually negotiated with clients.
Step 2: Classify TLS Termination Points
Identify every point in your infrastructure where TLS is terminated:
| Category | Examples | Typical Control | Migration Complexity |
|---|---|---|---|
| CDN/Edge | Cloudflare, Akamai, CloudFront | Vendor-managed | Low (vendor enables) |
| Cloud Load Balancer | AWS ALB/NLB, Azure App Gateway, GCP LB | Customer-configured | Low-Medium |
| Reverse Proxy | Nginx, HAProxy, Envoy | Customer-managed | Medium |
| Application Server | Tomcat, IIS, Kestrel, Node.js | Customer-managed | Medium |
| API Gateway | Kong, Apigee, AWS API Gateway | Varies | Low-Medium |
| Service Mesh | Istio, Linkerd | Customer-managed | Medium |
| VPN Concentrator | Cisco, Palo Alto, Fortinet | Customer-managed | Medium-High |
| Mail Server | Exchange, Postfix + TLS | Customer-managed | Medium |
Step 3: Enable Hybrid Key Exchange at CDN/Edge
Start with your outermost TLS termination — the CDN or edge:
Cloudflare: Hybrid key exchange (X25519Kyber768) is enabled by default for all customers. Verify:
- Dashboard → SSL/TLS → Edge Certificates → Verify cipher suites include hybrid
- No action required for most Cloudflare customers
AWS CloudFront/ALB:
// Security policy supporting hybrid key exchange
{
"SecurityPolicyName": "TLSv1.3_2024",
"SupportedGroups": [
"X25519MLKEM768",
"X25519",
"P-256"
]
}
Google Cloud Load Balancer: Hybrid key exchange enabled by default for TLS 1.3 connections. Verify via:
# Test from client
curl -v --curves X25519MLKEM768 https://your-gclb-domain.com
Step 4: Enable Hybrid on Reverse Proxies
For self-managed Nginx, HAProxy, or Envoy:
Nginx (OpenSSL 3.4+):
# /etc/nginx/conf.d/tls-pqc.conf
ssl_protocols TLSv1.3 TLSv1.2;
ssl_ecdh_curve X25519MLKEM768:X25519:prime256v1:secp384r1;
# Verify configuration
# nginx -t && nginx -s reload
HAProxy (3.0+ with OpenSSL 3.4+):
global
ssl-default-bind-ciphersuites TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-curves X25519MLKEM768:X25519:prime256v1
frontend https
bind *:443 ssl crt /etc/haproxy/certs/ curves X25519MLKEM768:X25519
Envoy (with BoringSSL):
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
common_tls_context:
tls_params:
ecdh_curves:
- X25519MLKEM768
- X25519
- P-256
Step 5: Enable Hybrid on Application Servers
Java (JDK 24+):
// System property
System.setProperty("jdk.tls.namedGroups", "x25519mlkem768,x25519,secp256r1");
// Or in JVM args
// -Djdk.tls.namedGroups=x25519mlkem768,x25519,secp256r1
Node.js (with OpenSSL 3.4+):
const https = require('https');
const tls = require('tls');
const server = https.createServer({
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem'),
// ecdhCurve setting for hybrid (when supported by linked OpenSSL)
ecdhCurve: 'X25519MLKEM768:X25519:prime256v1'
}, handler);
.NET (9+):
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(options =>
{
options.ConfigureHttpsDefaults(httpsOptions =>
{
httpsOptions.SslProtocols = SslProtocols.Tls13;
// .NET 9 supports hybrid key exchange via OS crypto library
});
});
Step 6: Verify Hybrid Deployment
After enabling, verify that hybrid key exchange is actually being used:
# Test with curl
curl -v --curves X25519MLKEM768 https://your-server.com 2>&1 | grep "SSL connection"
# Test with OpenSSL
openssl s_client -connect your-server.com:443 -groups X25519MLKEM768
# Expected output includes:
# Server Temp Key: X25519MLKEM768, 1184 bits
# Bulk verification with testssl.sh
./testssl.sh --pqc your-server.com
Step 7: Monitor and Address Failures
Common issues after enabling hybrid:
| Issue | Symptom | Resolution |
|---|---|---|
| Middlebox interference | Some clients fail to connect | Add classical fallback groups; update middlebox firmware |
| ClientHello fragmentation | Handshake timeout on some networks | Verify TCP MSS; consider TLS ClientHello padding |
| Outdated load balancer | LB doesn’t pass hybrid groups | Update LB firmware/software; terminate TLS at different point |
| Old OpenSSL | Configuration rejected | Upgrade to OpenSSL 3.4+ |
| Java client compatibility | Java clients fail to connect | Ensure server offers classical fallback groups |
Phase 2: Certificate Algorithm Migration (RSA/ECDSA → ML-DSA)
Why Certificate Migration Is More Complex
Certificate algorithm migration differs fundamentally from key exchange migration:
- Chain validation: Every entity in the certificate chain (root CA → intermediate CA → leaf) must use algorithms the client understands
- CA ecosystem: Certificate Authorities must support ML-DSA issuance
- Client support: All clients must be able to verify ML-DSA signatures
- Size impact: ML-DSA certificates are significantly larger than ECDSA/RSA certificates
- Cross-signing: Transition requires cross-signing between classical and PQC root CAs
- Certificate Transparency: CT logs must support PQC certificates
Certificate Size Impact
| Certificate Type | RSA-2048 | ECDSA P-256 | ML-DSA-65 | ML-DSA-87 |
|---|---|---|---|---|
| Public key | 256 bytes | 64 bytes | 1,952 bytes | 2,592 bytes |
| Signature | 256 bytes | 64 bytes | 3,309 bytes | 4,627 bytes |
| Typical leaf cert | ~1,500 bytes | ~800 bytes | ~6,000 bytes | ~8,000 bytes |
| 3-cert chain | ~4,500 bytes | ~2,400 bytes | ~18,000 bytes | ~24,000 bytes |
A full ML-DSA-87 certificate chain is approximately 5-10x larger than an equivalent ECDSA chain. This has real implications for:
- TLS handshake packet count (may require multiple TCP segments)
- Mobile network performance (bandwidth-constrained)
- IoT device memory (certificate parsing buffers)
Migration Strategy: Hybrid/Composite Certificates
Option 1: Dual Certificate (Two chains, client selects)
The server presents both a classical and a PQC certificate chain. Clients use whichever they support:
Server offers:
Chain A: Classical (ECDSA P-256 leaf + RSA intermediate + RSA root)
Chain B: PQC (ML-DSA-65 leaf + ML-DSA-65 intermediate + ML-DSA-65 root)
Client behavior:
- Modern client → verifies Chain B (PQC)
- Legacy client → verifies Chain A (classical)
Option 2: Composite Certificate (Single cert, dual signature)
A single certificate contains both classical and PQC public keys and signatures:
Certificate:
Public Key: Composite(ECDSA-P256 || ML-DSA-65)
Issuer Signature: Composite(ECDSA-P256-sig || ML-DSA-65-sig)
Verification: Both signatures must verify for certificate to be valid
Option 3: PQC-Only (future end state)
Once all clients support ML-DSA verification:
Certificate:
Public Key: ML-DSA-87
Issuer Signature: ML-DSA-87
No classical component
Certificate Migration Timeline
| Phase | Timeline | Action | Client Requirement |
|---|---|---|---|
| Now | 2026 | Enable hybrid key exchange (no cert change) | Clients supporting X25519MLKEM768 |
| Near-term | 2027-2028 | Deploy ML-DSA certificates for internal PKI | Internal clients only |
| Mid-term | 2028-2029 | Deploy composite certificates for public services | Clients with ML-DSA support |
| Long-term | 2030-2035 | Transition to PQC-only certificates | All clients must support ML-DSA |
Internal PKI Migration First
Organizations should start certificate migration with internal PKI where they control both sides:
Internal PKI Migration Steps:
1. Create ML-DSA-65 internal root CA
2. Issue ML-DSA-65 intermediate CA certificates
3. Configure internal services to use ML-DSA leaf certificates
4. Update internal clients to trust ML-DSA root CA
5. Verify all internal mTLS connections work with ML-DSA
6. Document lessons learned before public-facing migration
CDN/WAF Considerations
CDN-Specific Challenges
| Challenge | Description | Mitigation |
|---|---|---|
| Origin pull encryption | CDN-to-origin connections also need PQC | Enable hybrid on origin connections |
| Certificate caching | Larger certificates consume more cache | CDN providers adapting cache strategies |
| Edge node support | All edge nodes must support PQC | Major CDNs (Cloudflare, Akamai) have rolled out globally |
| Certificate size vs. TTFB | Larger certs increase Time To First Byte | Certificate compression (RFC 8879) mitigates |
| TLS termination location | Full site acceleration terminates TLS at edge | Ensure edge supports hybrid before enabling |
WAF/DPI Implications
Web Application Firewalls and Deep Packet Inspection devices that terminate and re-originate TLS must support PQC:
- Inline WAFs: Must support hybrid key exchange on both client-facing and server-facing connections
- TLS inspection devices: Must handle larger ClientHello messages without dropping
- IDS/IPS: Signature inspection of encrypted traffic requires updated TLS parsing
- DLP systems: May need updates to handle PQC-protected content inspection
Load Balancer Support Matrix
| Load Balancer | PQC Key Exchange | PQC Certificates | Notes |
|---|---|---|---|
| AWS ALB | ✓ (security policy) | Planned | Use TLSv1.3_2024 policy |
| AWS NLB | ✓ (passthrough + TLS) | Planned | TCP passthrough avoids issue |
| Azure App Gateway v2 | ✓ (preview) | Planned | Check region availability |
| GCP HTTPS LB | ✓ (default) | Planned | Enabled automatically |
| F5 BIG-IP (17.1+) | ✓ | Partial | Firmware update required |
| Citrix ADC (14.1+) | ✓ | Planned | Check firmware version |
| HAProxy (3.0+) | ✓ | ✓ | Requires OpenSSL 3.4+ |
| Nginx (latest + OpenSSL 3.4+) | ✓ | ✓ | Configuration required |
Performance Impact Analysis
TLS Handshake Performance (Hybrid Key Exchange)
| Metric | Classical (X25519) | Hybrid (X25519+ML-KEM-768) | Delta |
|---|---|---|---|
| Handshake bytes (client→server) | ~500 B | ~1,700 B | +1,200 B |
| Handshake bytes (server→client) | ~3,500 B | ~4,600 B | +1,100 B |
| Handshake CPU (client) | 0.12 ms | 0.16 ms | +0.04 ms |
| Handshake CPU (server) | 0.15 ms | 0.19 ms | +0.04 ms |
| Handshake RTTs | 1 | 1 (usually) | 0 |
| Time to First Byte (LAN) | 2.5 ms | 2.7 ms | +0.2 ms |
| Time to First Byte (100ms RTT) | 205 ms | 206 ms | +1 ms |
| Connections/sec (single core) | 6,500 | 5,200 | -20% |
TLS Handshake Performance (ML-DSA Certificates - Future)
| Metric | ECDSA P-256 Chain | ML-DSA-65 Chain | Delta |
|---|---|---|---|
| Certificate chain size | ~2,400 B | ~18,000 B | +15,600 B |
| Chain verification CPU | 0.45 ms | 0.24 ms | -0.21 ms (faster!) |
| Additional TCP segments | 0 | 1-2 | +1-2 packets |
| Handshake completion (LAN) | 3 ms | 3.5 ms | +0.5 ms |
| Handshake completion (100ms RTT) | 205 ms | 310 ms | +105 ms (extra RTT) |
Key observation: ML-DSA signature verification is faster than ECDSA, but the larger certificate requires more network packets, potentially adding a full RTT on constrained networks. Certificate compression (RFC 8879) and TLS 1.3’s improved handshake mitigate this.
Rollback Strategies
Key Exchange Rollback
If hybrid key exchange causes issues:
Immediate rollback (minutes):
# Nginx: Remove hybrid from curve list
ssl_ecdh_curve X25519:prime256v1:secp384r1;
# Reload: nginx -s reload
Gradual rollback (percentage-based):
# Use split_clients for gradual rollback
split_clients $remote_addr $tls_curves {
10% "X25519MLKEM768:X25519:prime256v1"; # 10% get hybrid
* "X25519:prime256v1"; # 90% classical only
}
server {
ssl_ecdh_curve $tls_curves;
}
Certificate Rollback
Certificate rollback is more complex — requires maintaining parallel certificate infrastructure:
- Keep classical certificates valid: Don’t revoke classical certs when deploying PQC
- Implement certificate selection logic: Server selects cert based on client capabilities
- Maintain dual CA hierarchy: Both classical and PQC CA chains remain operational
- Monitor client support: Track which percentage of clients successfully verify PQC certs
Monitoring PQC TLS Migration with QCecuring CBOM
QCecuring CBOM provides comprehensive TLS migration monitoring:
- Per-endpoint algorithm tracking: Shows which key exchange and signature algorithms are configured and actually negotiated at each TLS termination point
- Client compatibility metrics: Tracks what percentage of clients successfully negotiate hybrid vs. fall back to classical
- Migration progress dashboard: Organization-wide view of PQC adoption across all TLS endpoints
- Regression detection: Alerts when a previously PQC-enabled endpoint reverts to classical-only
- Certificate algorithm inventory: Tracks all certificate signature algorithms across the PKI
- Compliance timeline mapping: Shows migration progress against CNSA 2.0 and organizational deadlines
Key Takeaways
- TLS key exchange migration is the highest-priority PQC action — it stops HNDL exposure immediately
- Hybrid key exchange is deployable today — no waiting for standards, FIPS validation, or ecosystem maturity
- Start at the edge (CDN/load balancer) and work inward — fastest path to broad coverage
- Certificate migration is separate and less urgent — key exchange protects against HNDL; authentication protects against MITM (not quantum-threatened yet)
- Performance overhead for hybrid key exchange is negligible — typically <1 ms additional latency
- Certificate algorithm migration will add significant handshake size — plan for multi-packet handshakes with ML-DSA certificates
- Always maintain classical fallback during transition to handle legacy clients
- Internal PKI should migrate before public-facing — you control both sides and can iterate
- CDN/WAF devices must support PQC on both client-facing and origin-facing connections
- Rollback plans are essential — maintain ability to revert to classical quickly if issues emerge
- QCecuring CBOM tracks TLS migration progress across all endpoints, verifying that hybrid deployment achieves intended coverage