Post-Quantum Migration Starts With Your Crypto Debt
· 74 min read · Views --
Last updated on

Post-Quantum Migration Starts With Your Crypto Debt

Author: Alex Xiang


Post-quantum cryptography is often explained as an algorithm story: Shor’s algorithm threatens RSA and ECC, NIST has standardized ML-KEM, ML-DSA, and SLH-DSA, so everyone should replace old algorithms as soon as possible.

That statement is not wrong, but it sounds too much like a security-training slide. Inside a real company, the problem is rarely as clean as “replace algorithm A with algorithm B.” Where are certificates issued? Who signs the mobile app package? Which KMS wraps backup keys? Is the partner API signature documented? Can the old SDK be upgraded? These small questions decide whether the migration can actually move.

This article follows a fictional but realistic SaaS company called Northwind Notes, a B2B collaboration-documents and approval-workflow product. It has no national secrets and no mysterious hardware. It has public TLS, mobile apps, daily backups, partner APIs, and some historical baggage. The security lead gives the team one target: within 90 days, finish a post-quantum migration pilot. It does not need to replace everything, but it must make the inventory visible and prove one real, rollback-safe path.

Post-quantum cryptography migration roadmap

The Day-One Misunderstanding: Isn’t Everything Already HTTPS?

Northwind Notes’ first meeting moves quickly. When the business team hears “post-quantum migration,” their first reaction is that all public services already sit behind HTTPS and certificates are managed by the cloud provider. Surely the gateway team can just take a look.

The gateway team does produce a neat list: three public domains, load balancers in two regions, one CDN configuration, and an internal mTLS mesh. It looks tidy until the mobile lead asks, “Does app-package signing count?” The backup owner follows with, “What about the RSA wrapping key used for backups?” The partner-ecosystem team adds the final blow: “Several partner callbacks still use RSA-SHA256 signatures, and the signature-string format is written into contracts.”

That is the real beginning. PQC is not a TLS-only project. It is crypto-asset governance. Crypto assets do not live only with the security team or in infrastructure. They hide in release pipelines, mobile certificates, archive jobs, partner SDKs, old batch scripts, and many “we wrote this signer in a hurry years ago” utilities.

The company rewrites the 90-day goal into three sentences:

GoalNot forReal deliverable
Inventory crypto assetsA beautiful reportFind assets with long secrecy periods, slow upgrades, and unclear ownership
Run a hybrid pilotProve that a new algorithm is fashionableValidate compatibility, observability, rollback, and vendor boundaries
Build crypto agilityReplace every algorithm onceMake future algorithm changes avoid another company-wide code excavation

This shift matters. If post-quantum migration starts with “upgrade everything,” it easily becomes a large but vague security program. If it starts by admitting that the organization does not know where cryptography is used, it lands on executable lists, interfaces, and workflows.

The Inventory Is Not a CMDB; It Must Support Prioritization

In the first week, Northwind Notes does not buy a platform or introduce a new library. The security team sends a plain spreadsheet to every system owner. The fields are not administrative fields such as “system name, owner, note.” They are designed around migration decisions.

FieldExampleQuestion it answers
Asset IDCRYPTO-API-017Can later tests, risks, and tickets point to the same thing?
ScenarioPartner order-callback verificationIs this transport encryption, encryption at rest, or digital signature?
Algorithm and parametersRSA-2048 / SHA-256 / PKCS#1 v1.5How exposed is it to quantum risk, and does it have classical weaknesses too?
Data secrecy period7 yearsIs this a harvest-now-decrypt-later risk?
Key or certificate lifecycleRotated every 2 yearsWhere is the next natural change window?
Dependents8 partners, 3 internal servicesWho will be affected by migration?
Code or configuration locationapi-signature-service / v2 signerCan we find the actual implementation?
Vendor constraintHSM firmware does not yet support PQCIs the bottleneck outside the company?
Rollback pathFeature flag back to RSACan the pilot retreat if it fails?
Current observabilityOnly 401 count, no algorithm labelCan failures be diagnosed after rollout?

The spreadsheet quickly exposes several problems. Public TLS is clear because certificate management is centralized. Mobile app signing has expiry dates, but nobody has documented old-device verification behavior. Backup encryption uses cloud KMS, but the team has not checked how the KMS wraps keys internally. Partner RSA signatures are the worst: signing code is scattered across an old service and two SDKs, and some partners have private differences in field ordering.

By the end of week one, the team does not have a “12% migrated” number. It has a risk map that can be sorted.

AssetCurrent practiceMain risk90-day action
Public API TLSCloud load balancer, ECDHE plus ECDSA/RSA certsLong-lived sensitive traffic may be collected; middlebox compatibility unknownPilot hybrid KEM on an internal entry point, not full public traffic
Mobile app signingAndroid/iOS platform signing plus internal package signingOld verification chains may live for years; offline verification changes slowlyDocument the signing chain and rehearse dual signing
Backup encryptionAES data keys; RSA wrapping for historical archive keysBackups have 7 to 10-year secrecy periods, a classic harvest-now-decrypt-later caseMake new backups use a pluggable envelope; plan phased re-encryption for old backups
Partner API signaturesRSA-SHA256 request-level signaturesExternal migration is slow, protocol is hard-coded, verification failures are opaqueDesign v3 signature protocol and support dual verification first
Internal mTLSManaged by service meshClients are relatively uniform, but traffic is highChoose a low-risk internal link for handshake-observability pilot

This table is more valuable than picking algorithms early. It turns the meeting from “Should we switch to ML-KEM?” into “Which real path is worth proving in 90 days?”

Different Cryptographic Uses Need Different Migration Speeds

Northwind Notes divides assets into four groups: key exchange, transport-layer certificates, encryption at rest, and digital signatures. All relate to post-quantum work, but the migration difficulties differ.

TLS and mTLS depend on protocol stacks, clients, gateways, and middleboxes. A pilot can use hybrid key exchange, and failures can be routed back to classical settings. It is risky, but at least it is an online system with canarying and observability.

Backup encryption looks simpler because browser compatibility is not involved. The actual difficulty is the secrecy period. Backups are cold, but their value lasts. If an attacker obtains ciphertext today and can decrypt it years later, the business loss still happens. This scenario deserves earlier attention than many short-lived public sessions.

Mobile app signing and partner signatures are a different kind of trouble. There are many verifiers, and verification may happen years later. An app package, an audit archive, or a contract-callback log may still need to be validated long after signing. Signature migration cannot only ask “Can we verify it today?” It must ask “How will we prove the signature was valid later?” That introduces dual signatures, timestamps, legacy certificate retention, and verifier-version management.

The team first considers using public TLS as the 90-day pilot. It drops the idea for a practical reason: public clients are uncontrollable, the cloud provider’s production support for hybrid KEM is still on the roadmap, and forcing it would turn the project into vendor waiting. Instead, it runs two tracks in parallel:

Pilot trackWhy it was chosenWhy it is not the final state
Internal backup-envelope refactorLong data secrecy, controlled path, real reduction of long-term riskCovers only new backups; old backups still need phased treatment
Partner-signature v3 dual verificationRepresents the hardest external-coordination problemWithin 90 days, only two sandbox partners join

This is steadier than choosing the flashiest new algorithm. One pilot validates crypto agility for data at rest. The other validates external compatibility for signature migration. TLS remains on the roadmap, but it is no longer forced into the 90-day window.

Backup Track: Pull the Algorithm Out of the Code

The historical backup system is simple: every day it exports database and object-store snapshots, encrypts them with a random AES-256-GCM data key, wraps the data key with an RSA public key, and stores the ciphertext, wrapped key, and metadata in an archive bucket.

The old metadata looks like this:

{
  "version": "backup.v1",
  "data_cipher": "AES-256-GCM",
  "key_wrap": "RSA-OAEP-SHA256",
  "wrapped_data_key": "base64...",
  "nonce": "base64...",
  "created_at": "2026-01-04T03:10:12Z"
}

The problem is not AES. The problem is that key wrapping is hard-coded as RSA. Worse, the restore tool makes the same assumption: if it sees backup.v1, it unwraps with RSA-OAEP. Before using PQC or hybrid wrapping, the first step is not changing algorithms. It is versioning the envelope.

The second version changes the metadata to this shape:

{
  "version": "backup.v2",
  "data_cipher": "AES-256-GCM",
  "key_envelopes": [
    {
      "id": "rsa-2026-q1",
      "type": "rsa-oaep-sha256",
      "recipient": "backup-rsa-prod-01",
      "wrapped_data_key": "base64..."
    },
    {
      "id": "mlkem-2026-q1",
      "type": "ml-kem-768-hybrid-x25519",
      "recipient": "backup-pqc-pilot-01",
      "encapsulated_key": "base64...",
      "wrapped_data_key": "base64..."
    }
  ],
  "nonce": "base64...",
  "aad": {
    "tenant_region": "us-east-1",
    "retention_class": "seven_years"
  },
  "created_at": "2026-03-18T03:10:12Z"
}

The field names are not the important part. The design principles are: keep symmetric encryption for data; allow multiple key envelopes to coexist; let the restore tool choose the envelope it can use; give every envelope a version, recipient, and audit trail. Even if the first PQC path must be rolled back, the encrypted backup payload remains intact.

The configuration also moves out of application code:

backup_crypto_profile:
  name: seven-year-retention-pilot
  applies_to:
    retention_class: seven_years
    regions:
      - us-east-1
  data_cipher: AES-256-GCM
  envelopes:
    - id: rsa-2026-q1
      type: rsa-oaep-sha256
      required_for_restore: true
      recipient_key_ref: kms://backup/rsa/prod-01
    - id: pqc-hybrid-2026-q1
      type: ml-kem-768-hybrid-x25519
      required_for_restore: false
      recipient_key_ref: kms://backup/pqc/pilot-01
  rollout:
    mode: shadow
    tenant_percent: 5
    stop_on_restore_failure: true

In the first phase, mode: shadow means that the system writes the new envelope but still treats the RSA envelope as the primary restore path. A background job regularly performs restore drills with the PQC envelope. The system produces real data without betting production recovery on the new path.

This design also leaves room for later steps. After enough successful runtime, required_for_restore can change. When vendors and auditors are ready, the RSA envelope can move from “primary path” to “compatibility path.” Old backups can be re-encrypted by secrecy period instead of through one dangerous big-bang migration.

First Backup Failure: The Restore Tool Was Fine; The Runbook Was Wrong

On day 32, the team runs its first restore drill. Encryption and decryption unit tests pass. Shadow restore also works. The drill still fails for a small reason: the on-call runbook says “copy wrapped_data_key into the restore command,” but the new format has multiple envelopes. The engineer copies the RSA envelope field while selecting the PQC profile in the new restore tool. The tool throws a low-level “recipient mismatch.”

This is a typical migration failure. The algorithm implementation is not broken. The surrounding operational assumptions are. The tool error messages, runbooks, audit fields, and dashboards all assume “there is one key-wrapping method.” When the format becomes multi-envelope, those assumptions surface together.

The team makes three small changes:

backupctl restore \
  --archive s3://backup-archive/2026/03/18/tenant-1042.snapshot \
  --crypto-profile seven-year-retention-pilot \
  --envelope auto \
  --dry-run

--envelope auto lists available envelopes and explains why one was selected. --dry-run validates metadata and key-access permissions without restoring the database. The error message also changes from a low-level exception to an operator-facing explanation:

cannot use envelope pqc-hybrid-2026-q1:
  plugin can read archive metadata, but KMS recipient backup-pqc-pilot-01 is not granted to this restore role.
suggestion:
  run with --envelope rsa-2026-q1, or request restore role backup-pqc-restore-pilot.

This is not a cryptographic breakthrough, but it determines whether the pilot can enter production. Security projects often underestimate these human-machine interfaces. A real rollback and restore path is not the arrow in an architecture diagram. It is whether the person on call at night can follow the runbook correctly.

Partner Signatures: Dual Verification Before Asking Everyone To Change

Partner APIs live in another world. Northwind Notes has an open callback endpoint where partners push approval-status changes. The old protocol looks roughly like this:

POST /partner/v2/callback HTTP/1.1
X-Partner-Id: acme-sandbox
X-Timestamp: 1771272000
X-Signature-Alg: RSA-SHA256
X-Signature: base64...
Content-Type: application/json

The signature string is:

method + "\n" +
path + "\n" +
timestamp + "\n" +
sha256(body)

This protocol has old problems: the algorithm field is just a string; there is no version negotiation; partner public-key rotation happens through manual email; error logs only say “signature verification failed”; and SDKs contain private ordering logic for some partners. PQC simply shines light on these problems.

The new protocol does not ask partners to switch to post-quantum signatures immediately. The team first designs a v3 manifest where partners declare supported signature capabilities, and the host supports dual verification plus gradual enforcement.

{
  "partner_id": "partner-sandbox-17",
  "protocol": "northwind.partner-signature.v3",
  "valid_from": "2026-04-01T00:00:00Z",
  "keys": [
    {
      "kid": "rsa-2026-01",
      "alg": "rsa-pss-sha256",
      "use": "verify",
      "public_key": "pem-or-jwk-ref",
      "expires_at": "2026-12-31T23:59:59Z"
    },
    {
      "kid": "mldsa-pilot-01",
      "alg": "ml-dsa-65",
      "use": "verify",
      "public_key": "jwk-ref",
      "expires_at": "2026-09-30T23:59:59Z",
      "pilot": true
    }
  ],
  "policy": {
    "accept": "rsa_or_pqc",
    "require_timestamp_skew_seconds": 300,
    "log_signature_material": false
  }
}

Request headers also support multiple signatures:

X-Partner-Id: partner-sandbox-17
X-Signature-Input: method path timestamp body-sha256
X-Signature-RSA: kid=rsa-2026-01; sig=base64...
X-Signature-PQC: kid=mldsa-pilot-01; sig=base64...

During the pilot, the policy is rsa_or_pqc. If RSA verification passes, the request is still accepted; the PQC verification result goes into logs and dashboards but does not affect business. After two sandbox partners meet the success target for 30 consecutive days, one low-risk endpoint can move to rsa_and_pqc, requiring both signatures. Only much later should some new endpoints accept only PQC or hybrid signatures.

A subtle point matters here: dual signing is not just adding a field. The signature input must be identical. Error codes must say which signature failed. Replay protection must not become ambiguous because two signatures exist. SDKs must be able to generate test vectors. Otherwise partners only see 401, and both sides start pasting logs into chat.

Partner Failure Sample: Signature Failure Is Not One Error

On day 51, a sandbox partner connects v3 and the PQC signature keeps failing. At first everyone suspects incompatible algorithm libraries. The actual issue is path normalization. The partner SDK signs /callback; the gateway verifies /partner/v3/callback. The old RSA SDK had the same problem, but the old service silently rewrote the path before verification, and nobody wrote that behavior down.

The team splits signature errors into finer categories:

Error codeMeaningCounts as algorithm failure?
signature.input_mismatchThe two sides used different signature inputNo, protocol-integration issue
signature.key_not_foundNo public key for the given kidNo, configuration or rotation issue
signature.unsupported_algHost does not support the algorithmYes, capability-negotiation issue
signature.verify_failedInput and key match, but verification failsYes, implementation issue or tampering
signature.clock_skewTimestamp outside the allowed windowNo, replay-protection issue

It also creates public test vectors for SDKs and partner documentation:

{
  "case": "v3-path-normalization",
  "method": "POST",
  "path": "/partner/v3/callback",
  "timestamp": "1771272000",
  "body_sha256": "d4735e3a265e16eee03f59718b9b5d03...",
  "signature_input": "POST\n/partner/v3/callback\n1771272000\nd4735e3a...",
  "expected": {
    "rsa_pss_sha256": "base64...",
    "ml_dsa_65": "base64..."
  }
}

The vectors contain no real partner names, keys, or request bodies. They preserve protocol behavior. Their job is to turn “maybe your library is incompatible” into locally reproducible input and output.

TLS Did Not Disappear; It Returned To Its Proper Place

This article is not saying TLS is unimportant. Northwind Notes also inventories TLS. It simply does not treat TLS as the only battlefield for the 90-day pilot.

The TLS inventory includes:

ItemChecks
Public domainsCertificate algorithm, certificate chain, expiry, CDN and load-balancer support roadmap
Internal mTLSService-mesh version, sidecar update rhythm, failure metrics
Client distributionBrowsers, mobile apps, old SDKs, enterprise proxies
MiddleboxesWhether WAF, API gateway, or enterprise proxy drops unknown extensions
ObservabilityWhether handshake failures can be grouped by protocol, cipher, and client version

On day 60, the team chooses one internal path for early research: mTLS from the document service to the audit-archive service. Traffic is stable, clients are controlled sidecars, data has long-term audit value, and failures can fall back to the old target.

The pilot configuration does not go straight to “all PQC.” It has explicit switches:

mesh_tls_policy:
  service: audit-archive
  client_selector:
    namespace: docs
  key_exchange:
    mode: hybrid
    classical: x25519
    post_quantum: ml-kem-768
  rollout:
    percent: 10
    fallback: classical_only
    abort_if:
      handshake_error_rate_gt: 0.2%
      p95_handshake_ms_increase_gt: 15
  telemetry:
    label_algorithm: true
    label_client_version: true

The valuable part is telemetry. Previously, a handshake failure was just a TLS error. Now it can be grouped by sidecar version, negotiation mode, and error family. Without that dimension, a hybrid-mode incident can only be handled by global rollback.

Testing: Do Not Only Test Encryption and Decryption

Northwind Notes splits testing into four layers. Algorithm correctness is only the first layer; the other three are closer to engineering reality.

Test layerBackup exampleSignature exampleTLS example
CorrectnessThe same backup restores through both RSA and PQC envelopesTest vectors verify successfullySidecar completes hybrid handshake
CompatibilityOld restore tool rejects new format with a clear errorv2 partners are unaffected by v3 manifestsOld sidecars automatically use classical mode
Fault injectionRSA restore works when PQC KMS key is unavailableExpired kid, inconsistent path, clock skewMiddlebox drops extension; handshake timeout
Operational drillOn-call restores a sample from the runbookPartner generates signature locally from docsSRE triggers rollback from metrics

Not everything is declared “complete only if fully automated.” Some tests must be automated, such as test vectors and restore dry-runs. Some tests need people, especially runbook drills. Crypto migration changes operations, and people are part of the system.

The weekly review watches four metrics:

MetricTarget
Owner coverage for high-priority crypto assets100%
New backup v2 envelope write successAbove 99.99%
PQC shadow-restore success100% for 14 consecutive days
Classifiable v3 signature errorsAbove 95%

There is no large “percentage migrated” number because a 90-day pilot should not pretend to complete a company-wide migration. It must prove that assets can be seen, failures can be explained, and paths can be rolled back.

Rollout And Rollback: Migration Must Allow Failure Without Incident

The rollout plan is conservative.

Backup track:

StageBehaviorRollback
0Read only old v1; do not write new formatNo rollback needed
15% tenants write v2; RSA envelope remains the primary restore pathStop writing v2; new backups return to v1
2Write v2 for all tenants; background shadow-restore through PQC envelopeDisable PQC envelope; keep RSA
3Selected tenants’ restore drills prefer PQC envelopeRestore command switches back to RSA envelope

Partner-signature track:

StageBehaviorRollback
0v3 manifest registered only in sandboxDelete manifest; v2 unaffected
1Production accepts v2; v3 dual signature only records resultsDisable v3 verification worker
2Two low-risk partners use rsa_or_pqcChange partner policy back to rsa_only
3One low-risk endpoint uses rsa_and_pqcRevert policy and retain failure samples

The core idea is that every step can return to a known-safe classical path while preserving observability. Rollback is not admitting defeat. It is part of the pilot design. Without rollback, crypto migration encourages delay because nobody wants to own a full-site verification failure.

What Was Actually Delivered After 90 Days

On day 90, Northwind Notes does not announce “we have completed post-quantum migration.” That is the mature conclusion. It delivers a set of simpler, more sustainable artifacts:

DeliverableValue
72 crypto assets inventoried, 28 high priorityBudgeting and scheduling now have evidence
Backup v2 envelope format and restore toolingLong-secrecy data now has a migration entry point
Partner-signature v3 protocol, manifest, and SDK test vectorsExternal coordination becomes a contract, not a chat thread
mTLS hybrid-handshake telemetry fieldsFuture TLS pilots can explain failures
Vendor issue listHSM, KMS, CDN, and mobile-platform support timelines are recorded
Rollout and rollback templatesOther systems can reuse the same change pattern

Many things remain unfinished. Old backups are not fully re-encrypted. Public TLS does not enable PQC. Mobile app signing is still at dual-signing rehearsal. Only two sandbox partners have joined. None of that is embarrassing. The 90-day target solves “how do we start?” It does not swallow several years of work.

The most valuable output is a set of engineering habits:

HabitWhy it matters
Do not hard-code algorithms in business codeStandards, libraries, and vendors will change
Give every key and certificate an ownerUnowned crypto assets are the most dangerous
Support dual tracks for new protocolsExternal ecosystems need migration buffers
Classify errorsA plain “failure” cannot drive collaboration
Update runbooks with toolsMigration affects real operations, not just code

That is what I mean by crypto agility. It is not a framework name or a vendor product. It is an organizational ability: know where cryptography is used, know who owns it, know how to test, and know how to retreat.

A Small Checklist To Start With

If you are starting a similar program, these questions are better than “When can we fully switch to PQC?”

QuestionIf you cannot answer it
Which data remains valuable five years after being stolen today?Risk prioritization is not established
Which signatures must remain verifiable years later?Signature migration ignores long-term evidence
Which cryptographic capabilities depend on vendors?The timeline is not purely internal
Which algorithms are hard-coded in business repositories?Migration will become repository-by-repository surgery
Which failures currently show only 401 or TLS error?Compatibility issues will be hard to diagnose after rollout
Is there one real link that can be piloted and rolled back quickly?The project may stay in documents

Post-quantum cryptography absolutely has algorithmic problems. But inside a company, post-quantum migration first becomes an asset problem, a protocol problem, a rollout problem, and a coordination problem. The best next step is not replacing RSA everywhere, nor waiting until a practical quantum computer forces a meeting. It is exposing crypto debt and running one real path.

When large-scale migration eventually becomes necessary, a prepared team will not search repositories for signing functions at the last minute. It will open the inventory, adjust the profile, canary the change, watch metrics, and roll back if needed. That is the part worth building early.