Post‑Quantum Crypto in 2025: Kyber‑Hybrid TLS, PQ Signatures, and a Developer Migration Playbook
If you handle sensitive data with a shelf life beyond a couple of years, you should assume a motivated adversary is recording your encrypted traffic today to decrypt it later. That “harvest‑now, decrypt‑later” threat model has gone from niche worry to mainstream planning assumption. The good news: in 2025, quantum‑safe primitives have matured enough to take the first big step—upgrade your transport privacy to hybrid post‑quantum key agreement, and begin a staged rollout of PQ signatures in your supply chain and code signing.
This article is an opinionated, practical playbook for software and platform teams. It focuses on:
- Turning on hybrid X25519+Kyber for TLS without blowing SLOs
- Using the default hybrid in OpenSSH correctly (and testing Kyber variants where it makes sense)
- Planning for PQ signatures in CI/CD, container signing (Sigstore), and code signing
- Inventories, rotations, and compatibility strategies that won’t break older clients
It’s detailed because results beat vibes in crypto migrations.
Executive Summary
- Prioritize confidentiality first. Hybrid PQ key exchange in TLS and SSH mitigates harvest‑now, decrypt‑later risks without waiting for PQ signatures to be universally supported in PKI.
- Use Kyber768 in hybrid with X25519 for TLS 1.3/QUIC. Keep classical ECDSA certificates for now; don’t try to swap your server cert chain to PQ signatures yet unless you control both ends.
- For SSH, OpenSSH’s default hybrid sntrup761x25519 is already a strong posture; treat Kyber‑SSH as an opt‑in experiment for controlled fleets.
- PQ signatures for software supply chain: adopt dual‑signing (ECDSA + ML‑DSA a.k.a. Dilithium) for artifacts and policies, integrate with Sigstore/cosign and transparency logs, and roll out verification gradually.
- Expect bigger keys/signatures and small CPU bumps. Measure handshake size, p99 handshake time, error rates, and storage impacts; bake a 10–20% CPU headroom into TLS termination pools during canaries.
- Stay agile. Use configuration and policy to negotiate algorithms, track capabilities, and enable rapid fallback.
Primer: What You’re Deploying and Why
The risk: harvest‑now, decrypt‑later
Adversaries can record your session ciphertext today and decrypt it years later if classical cryptography is broken by a sufficiently capable quantum computer. Even if you don’t think that’s imminent, the half‑life of many secrets (PHI, PII, trade secrets, long‑lived tokens, legal records) easily spans five to ten years. Transport confidentiality is the fastest lever to reduce that risk.
Building blocks
- Key encapsulation mechanisms (KEMs): Used in key exchange to agree on a shared secret. NIST selected CRYSTALS‑Kyber (standardized as ML‑KEM) as the primary KEM. Security levels are roughly “768” for ~128‑bit classical security, and “1024” for ~192‑bit.
- Digital signatures: Used for identity/authentication (certificates, code signing). NIST standardized CRYSTALS‑Dilithium (ML‑DSA), and a hash‑based scheme SPHINCS+ (SLH‑DSA). Falcon is another lattice‑based signature expected to land with more constrained device use cases; it has fast verification but more complex implementation constraints.
Why hybrid now? Because the public‑key operations inside TLS and SSH are separable from certificates. You can keep your classical certificates (ECDSA P‑256) but negotiate a key using a hybrid of a classical ECDH (X25519) and a PQ KEM (Kyber). If either remains unbroken, forward secrecy holds.
Sizes and performance (order‑of‑magnitude)
- Kyber768 KEM: public key ~1.2 KB, ciphertext ~1.1 KB. Encaps/decaps are fast on modern CPUs (microseconds), faster than RSA‑2048, comparable or modestly slower than X25519.
- Dilithium2 signatures: public key ~1.3 KB, signature ~2.4 KB; Dilithium3/5 larger. Verification/creation are fast enough for server use; signatures are substantially larger than ECDSA.
- SPHINCS+ signatures: public keys small, signatures large (~8–30 KB) but pure hash‑based, great for high‑assurance or offline signatures.
Impact: Expect TLS handshakes to grow by a few kilobytes when hybrid is enabled and increased CPU per handshake that is typically dwarfed by application processing. Signature adoption will inflate artifact sizes and log entries, plan registry/storage headroom accordingly.
Where PQC Lands in 2025
TLS 1.3 and QUIC: hybrid X25519+Kyber
- Negotiation: TLS 1.3 supports negotiating key exchange “groups.” Hybrid groups combining X25519 and Kyber768 have been widely tested. Many stacks use a standardized identifier like X25519Kyber768 (early deployments used Draft00 names).
- Certificates remain classical: Keep your ECDSA certificates and chains. The PQ piece covers key establishment, not certificate verification.
- QUIC (HTTP/3): uses TLS 1.3 under the hood, so enabling hybrid affects QUIC the same way. Watch for initial flight size with larger ClientHello/ServerHello.
What you get: immediate protection of session confidentiality against future decryption, while maintaining interop with clients that ignore unknown groups by negotiating X25519 only.
SSH: hybrid by default, Kyber optional
- OpenSSH 9.x defaults to sntrup761x25519‑sha512@openssh.com for key exchange. That’s a hybrid of NTRU Prime (sntrup761) with X25519. It’s a strong, vetted choice and has been the default for years.
- Kyber in SSH exists via oqs‑patched OpenSSH builds. It’s fine to evaluate in controlled environments, but the mainstream default remains sntrup761x25519. Don’t force Kyber‑SSH on heterogeneous fleets unless you control both sides and have a rollback plan.
Code signing and supply chain
- X.509 and WebPKI: PQ signatures inside browser‑trusted chains are not yet ubiquitous. Stick with ECDSA server certs; use hybrid KEX for TLS.
- Enterprise PKI/code signing: You can begin dual‑signing artifacts with ECDSA and ML‑DSA (Dilithium) and capturing both in transparency logs. Policies can require “at least one PQ signature” for high‑assurance paths while maintaining classical signatures for widespread compatibility.
- Sigstore: cosign and Rekor have patterns for multiple signatures per artifact and recording them in transparency logs. Consumers can verify either classical, PQ, or both according to policy.
Migration Strategy: A Playbook
1) Inventory and scope
- Catalog every place you use public‑key crypto:
- TLS termination (ingress/egress), service‑to‑service mTLS, databases, message brokers
- SSH bastions and automation
- Build systems (code signing, artifact signing, container signing, SBOM signing)
- Admin tooling: package repositories, OTA, mobile app signing
- Capture versions and crypto libraries: OpenSSL/BoringSSL/wolfSSL/Go crypto, Java, .NET, libssh/OpenSSH, HSMs/PKCS#11 vendors.
- Record data sensitivity and shelf‑life per system: which sessions, if decrypted in 5–10 years, would materially harm you?
Outcome: a prioritized backlog. TLS/mTLS for high‑shelf‑life data should be first.
2) Choose algorithms and parameters
- TLS KEX: prefer X25519Kyber768 (hybrid). Consider Kyber512 variants only for extremely constrained links after measurement; most orgs should stick to 768.
- SSH: keep sntrup761x25519 default; evaluate Kyber hybrids via oqs‑OpenSSH where you control both ends.
- Signatures:
- Artifacts: Dilithium2 or Dilithium3 (ML‑DSA) for general use; Dilithium3 for higher margin, SPHINCS+ for root/firmware/offline.
- Leave server certs as ECDSA P‑256 for now; explore dual chains/attestations inside your enterprise PKI if you control clients.
3) Design rollouts with graceful fallback
- Canary: enable hybrid groups for 1–5% of traffic behind a feature flag. Track handshake success rate, abort reasons, handshake RTT distributions, and p99 CPU on terminators.
- Fallback: ensure servers advertise X25519 first with hybrid next; or advertise hybrid first and accept client fallback behavior. Verify no middleboxes choke on larger ClientHello.
- Version gates: only enable on stacks you’ve verified (OpenSSL 3.x with oqs‑provider, BoringSSL builds with hybrid groups, wolfSSL with PQC enabled, etc.).
4) Key and certificate rotation planning
- KEX doesn’t change server certificates. However, plan to shorten certificate lifetimes (e.g., 90‑day) to maintain agility. Automate rotations via ACME where applicable.
- PQ signature keys (for artifacts) are larger; update HSM and KMS policies. Many HSMs are still catching up—consider software‑based keys with robust access controls for PQ pilots, and rotate into HSMs once vendor support lands.
- Backup and escrow: KEM keys are ephemeral; do not “backup” ephemeral secrets. For signature keys, ensure recovery and revocation plans cover both classical and PQ keys.
5) Crypto agility in config management
- Centralize the following as configuration, not code:
- TLS groups list and ordering
- Allowed signature algorithms for artifact verification
- Enforcement thresholds (e.g., require PQ signatures in prod but allow classical in dev)
- Build metrics and alerts:
- Ratio of handshakes using hybrid vs classical
- Error codes for handshake failures
- Artifact signature verification percentages by algorithm
6) Communicate and train
- Educate platform owners about larger handshakes and signature sizes. Align SLOs and capacity plans.
- Publish rollback runbooks for each system.
- Document the why: reduce harvest‑now, decrypt‑later risk; maintain interoperability; keep options open for future certificate upgrades.
Practical How‑To: TLS
Below are patterns for popular stacks. Exact names of hybrid groups vary slightly between libraries (e.g., X25519Kyber768 vs X25519Kyber768Draft00). Always list supported groups to confirm names on your build.
OpenSSL 3.x with the oqs‑provider
- Build and install the Open Quantum Safe provider:
bash# Prereqs: OpenSSL 3.0+ installed # Build oqs-provider git clone https://github.com/open-quantum-safe/oqs-provider.git cd oqs-provider mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=Release .. make -j$(nproc) sudo make install # Verify provider loads openssl list -providers -provider-path /usr/local/lib64/ossl-modules
- List supported TLS groups (look for Kyber hybrids):
bashopenssl list -groups -provider oqsprovider -provider default
- Test a client handshake offering hybrid first:
bash# Replace name according to what 'openssl list -groups' shows openssl s_client -groups X25519Kyber768:X25519 -tls1_3 -connect your.server:443 \ -provider oqsprovider -provider default
- nginx with OpenSSL 3.x: use ssl_conf_command to set groups:
nginxhttp { # ... server { listen 443 ssl; ssl_protocols TLSv1.3; # prefer TLS1.3 # Keep your ECDSA certs ssl_certificate /etc/nginx/certs/server-fullchain.pem; ssl_certificate_key /etc/nginx/certs/server-key.pem; # Prefer hybrid; ensure X25519 present for fallback ssl_conf_command Groups X25519Kyber768:X25519:secp256r1; # Reasonable TLS 1.3 ciphers ssl_ciphers TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256; # ... rest of config } }
If your OpenSSL build uses the Draft00 name, try:
nginxssl_conf_command Groups X25519Kyber768Draft00:X25519;
- Apache httpd (mod_ssl) with OpenSSL 3.x:
apache<VirtualHost *:443> SSLEngine on SSLProtocol TLSv1.3 SSLCertificateFile /etc/httpd/certs/server.crt SSLCertificateKeyFile /etc/httpd/certs/server.key # Set TLS1.3 groups (aka "curves" in older docs) SSLOpenSSLConfCmd Groups X25519Kyber768:X25519:secp256r1 SSLCipherSuite TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 </VirtualHost>
- HAProxy built against OpenSSL 3.x:
haproxyglobal ssl-server-verify none defaults mode http option httplog timeout connect 5s timeout client 30s timeout server 30s frontend fe_https bind :443 ssl crt /etc/haproxy/certs/server.pem \ alpn h2,http/1.1 \ ciphers TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 \ groups X25519Kyber768:X25519 default_backend be_app
- Envoy (BoringSSL):
yamlstatic_resources: listeners: - name: listener_0 address: socket_address: { address: 0.0.0.0, port_value: 443 } filter_chains: - 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: tls_minimum_protocol_version: TLSv1_3 # Use the exact group token supported by your Envoy/BoringSSL build key_update_frequency: 0 tls_certificate_sds_secret_configs: - name: server-cert # custom TLS params or BoringSSL flags may be required to enable hybrid groups
Envoy’s configuration for key exchange groups is build‑dependent; validate via admin /certs and runtime flags, and roll canaries.
Client testing
- curl (OpenSSL/wolfSSL builds):
bashcurl --tlsv1.3 --curves X25519Kyber768 https://your.server/
- OpenSSL s_client: shown above. Compare handshake transcript sizes with and without hybrid.
- Chrome/Firefox: modern builds will happily negotiate hybrid groups if advertised by the server and supported by the TLS library; browser flags are usually not required for negotiated hybrid KEX because certificates remain classical.
Observability
- Export TLS metrics from terminators: ratio of negotiated groups, handshake failure codes, average handshake bytes sent/received, p95/p99 handshake time, CPU per handshake.
- Watch QUIC initial flights: hybrid adds bytes to ClientHello and EncryptedExtensions; ensure congestion control and MTU are comfortable.
Practical How‑To: SSH
Confirm and enforce hybrid default in OpenSSH
- List supported KEX on a host:
bashssh -Q kex
You should see sntrup761x25519‑sha512@openssh.com.
- Enforce on servers (sshd_config):
confKexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256
- Enforce on clients (ssh_config):
confHost * KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256
This preserves a strong hybrid first, with classical fallback.
Evaluating Kyber‑SSH (optional, controlled fleets)
- Use OQS‑OpenSSH builds to access kyber*-x25519 hybrids. Both client and server must support the same KEX names.
- Restrict to a lab environment first; measure handshake sizes and CPU; confirm that automation (Ansible, CI) works end‑to‑end.
- Keep a rollback to stock OpenSSH packages.
Monitoring
- Parse sshd logs for negotiated KEX, failed handshakes, and identify clients that never use hybrid (targets for upgrade).
Practical How‑To: PQ Signatures in CI/CD and Code Signing
You don’t need PQ signatures to protect transport confidentiality today. But you should begin integrating them into your supply chain to shorten your lead time and avoid future scrambles.
Patterns for artifact signing
- Dual‑sign artifacts now: produce both a classical (ECDSA) and PQ (ML‑DSA/Dilithium) signature for the same digest. Store both alongside the artifact.
- Verify according to policy: accept classical in general, require PQ for high‑assurance environments, and gradually tighten.
Sigstore/cosign
- Sign twice and attach both to the image:
bash# Classical signature cosign sign --key cosign-classical.key $IMAGE # PQ signature (Dilithium via experimental key type or external signer) cosign sign --key cosign-dilithium.key --attachment signature $IMAGE # Record both in Rekor transparency log cosign triangulate $IMAGE cosign verify --key cosign-classical.pub $IMAGE cosign verify --key cosign-dilithium.pub $IMAGE
- Policy example (cosign policy.yaml):
yamltrustPolicies: - name: require-two-sigs scopes: ["*"] authorities: - key: kms: "file:cosign-classical.pub" - key: kms: "file:cosign-dilithium.pub" requireAttestations: false
- In Kubernetes admission or CI verification, enforce “one of” or “both” signatures. Start with audit‑only mode to collect coverage.
TUF and in‑toto
- TUF metadata can carry multiple signatures per role. Add a PQ signature to root/targets metadata signed by the same role keys, and configure clients to accept any or both depending on environment.
- In‑toto attestations: add PQ signatures to attestations that cannot be forged by classical attackers if ECDSA is compromised.
Enterprise code signing
- Windows/macOS: keep classical signatures for OS trust today. Add PQ signatures as detached metadata (e.g., alongside installers, update manifests, or in transparency logs) and verify in your enterprise deployment tooling.
- Firmware/IoT: consider SPHINCS+ for long‑lived firmware roots; Dilithium for update packages. Measure flash and RAM impacts.
Keys and HSMs
- HSM support for ML‑DSA is emerging. If your HSM does not support PQ yet:
- Use a software key in a hardened signer service with short‑lived issuance tokens and tight isolation.
- Plan a migration path to HSM‑resident keys later. Keep PQ key IDs/versioning ready.
Capacity and Performance Planning
Expect the following impacts; measure rather than guess.
- TLS handshakes:
- Larger ClientHello/ServerHello by a few KB when hybrid is negotiated.
- CPU: Kyber768 operations are fast; overall TLS handshake CPU typically increases by single‑digit percentages. If you terminate 30–50k handshakes/sec per node, budget an extra 10–20% headroom during canary.
- QUIC initial flight: ensure PMTU 1200‑byte path remains safe; larger packets may split across multiple datagrams; test loss.
- SSH:
- Negligible CPU/latency impact relative to network RTT and authentication. Hybrid defaults have been stable for years.
- Storage and bandwidth:
- Artifact signatures: adding Dilithium roughly adds a few KB per signature. Multiply by number of layers/images and registry scale.
- Transparency logs: expect log growth; monitor Rekor and internal CT‑like systems.
Measure:
- p50/p95/p99 TLS handshake time and its contribution to request latency
- Handshake failure rate by group, client OS/browser, and geography
- Terminator CPU and memory usage per connection
- Artifact size growth and registry egress
Interop Pitfalls and Mitigations
- Middleboxes and DPI: some legacy boxes mishandle larger ClientHello or unknown groups. Mitigation: advertise X25519 alongside hybrid; canary; observe failures; keep a per‑AS or per‑CIDR override to disable hybrid if necessary.
- Library naming mismatches: confirm whether your lib uses X25519Kyber768 or X25519Kyber768Draft00. List supported groups at runtime and configure accordingly.
- TLS 1.2: hybrids land in TLS 1.3. Ensure clients can do TLS 1.3; otherwise they’ll fall back to classical TLS 1.2.
- Session resumption/PSK: resumes inherit initial handshake confidentiality. No additional configurations needed, but confirm ticket sizes and lifetime policies.
- HSM and PKCS#11 gaps: for PQ signatures, many HSMs aren’t there yet. Use an interim signer plan; isolate and monitor; move to HSM when vendor support arrives.
- Certificate authorities: public CAs are not issuing browser‑trusted PQ‑signed certs widely. Do not attempt to deploy PQ‑only server certs to the public internet today. Stick with hybrid KEX.
Security Posture and Auditing
- Add telemetry dimensions for crypto:
- TLS negotiated group
- TLS version
- Signature algorithm used in artifact verification
- Alert on:
- Spike in handshake failures after enabling hybrid
- Unexpected drop in hybrid negotiation ratio
- Verification failures on PQ signatures in CI or admission controllers
- Log:
- For SSH, negotiated KEX per session for a rolling window; identify old clients stuck on classical only.
- For supply chain, log both signature verifications and include algorithm IDs for audit.
Roadmap: 2025–2026 Outlook
- Standards:
- NIST PQC selections are standardized as ML‑KEM (Kyber), ML‑DSA (Dilithium), and SLH‑DSA (SPHINCS+), with publications rolling out 2024–2025.
- IETF LAMPS is standardizing PQ certs and composite/hybrid signatures; adoption in browsers will lag transport KEX by design.
- TLS hybrid group identifiers have stabilized; expect fewer name changes going forward.
- Ecosystem:
- Cloud providers, CDNs, and large properties have broadly validated hybrid KEX at scale.
- HSM vendor support for Dilithium and Kyber will improve; plan upgrades aligned with your signer needs.
- Sigstore and similar ecosystems will make dual‑sign policies more turnkey.
Your north star: confidentiality via hybrid KEX now, integrity via dual‑signing now, and a path to PQ‑native identity once PKI ecosystems catch up.
30/60/90‑Day Checklist
Day 0–30: Assess and canary
- Complete crypto inventory and prioritize systems handling long‑shelf‑life data.
- Add TLS telemetry for negotiated groups and handshake metrics.
- Build a test terminator with hybrid enabled; prove end‑to‑end with synthetic clients.
- Canary hybrid on a low‑traffic cluster behind a feature flag; monitor errors and latencies.
- Enforce sntrup761x25519 in SSH fleet; audit clients for compliance.
- Pilot dual‑signing in CI for a small service’s container images; verify in CI only.
Day 31–60: Expand and harden
- Roll hybrid TLS to 25–50% of traffic during off‑peak windows; tune ciphers/group ordering.
- Update runbooks with rollback and per‑client overrides; document known incompatible agents.
- Extend dual‑signing to core services; add admission‑webhook audit mode verifying both signatures.
- Define PQ key management procedures; ready a signer service (software‑based if HSMs aren’t ready).
Day 61–90: Enforce and normalize
- Aim for >80% of public TLS handshakes negotiating hybrid; keep global fallbacks for problematic networks.
- Flip artifact verification policy to require at least one PQ signature in staging; plan prod enforcement for selected namespaces.
- Produce a quarterly report: handshake ratios, failure causes, artifact signature coverage, storage impact, and next‑step roadmap.
Frequently Asked Practical Questions
- Do I need to change certificates to get hybrid TLS? No. Keep your existing ECDSA certificates. Hybrid affects key exchange, not certificate signatures.
- Which Kyber level should I choose? Kyber768 (ML‑KEM Level 3) is the practical default for most server deployments. Kyber1024 is larger; measure before adopting.
- Will this break old clients? Properly configured, no. Clients that don’t know hybrid groups will negotiate X25519 and still succeed. Canary to catch rare middlebox issues.
- Can I turn off classical algorithms entirely? Not on the open internet. In closed ecosystems where you control every client, you can experiment with PQ‑only, but maintain a documented rollback.
- What about OCSP/CT and PQ? Those remain classical today in public PKI flows. That’s fine because your immediate goal is transport confidentiality, not PQ‑native identity.
References and Further Reading
- NIST PQC project overview: https://csrc.nist.gov/projects/post-quantum-cryptography
- NIST draft FIPS: ML‑KEM (Kyber), ML‑DSA (Dilithium), SLH‑DSA (SPHINCS+): https://csrc.nist.gov/publications
- IETF TLS 1.3 (RFC 8446): https://www.rfc-editor.org/rfc/rfc8446
- IETF drafts on hybrid key exchange for TLS 1.3 (naming and design): IETF TLS WG, LAMPS WG
- Open Quantum Safe project (liboqs, oqs‑provider): https://openquantumsafe.org/
- Cloudflare and Google experiments on X25519+Kyber: engineering blogs discuss traffic percentages, latency, and interop
- OpenSSH sntrup761 hybrid default announcement: OpenSSH release notes and mailing list
- Sigstore project (cosign, Rekor, Fulcio): https://sigstore.dev/
Closing Opinion
If you do nothing else in 2025, enable hybrid TLS. It’s the cleanest, least disruptive step to inoculate your transport confidentiality against future quantum advances. Treat PQ signatures as a supply‑chain posture you can adopt incrementally with dual‑signing and policy, without waiting for browsers and CAs to catch up. Measure, canary, and keep algorithm choices in configuration so you can move as the standards and ecosystems cross the last mile. That’s crypto agility you can operationalize—today.