Skip to content

Crypto-Agility Guide

This guide covers algorithm migration for Certificate Authorities and credentials - transitioning from classical to post-quantum cryptography.

Crypto-agility is the ability to migrate cryptographic algorithms without redesigning the PKI infrastructure. This is critical for:

  • Quantum threat: Quantum computers will eventually break RSA and ECC
  • Store Now, Decrypt Later (SNDL): Encrypted data captured today can be decrypted later
  • Algorithm deprecation: Algorithms become weak over time (MD5, SHA-1, RSA-1024)
  • Compliance requirements: Regulatory changes may require new algorithms
StrategyPathBackward Compatibility
DirectEC → ML-DSANone - break with legacy
Via HybridEC → Catalyst → ML-DSAYes - gradual transition
Multi-ProfileEC + ML-DSA simultaneouslyYes - parallel algorithms

Recommended path: Classical → Hybrid → Post-Quantum

┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Classical │────►│ Hybrid │────►│ PQC │
│ (EC/RSA) │ │ (Catalyst) │ │ (ML-DSA) │
└─────────────┘ └─────────────┘ └─────────────┘

CA rotation creates a new version of the CA with different algorithms while maintaining certificate chain continuity.

Terminal window
# CA versioning after rotations:
ca/
├── ca.crt # Symlink to active version
├── ca.key # Symlink to active version
└── versions/
├── v1/ # Original (EC P-384)
├── ca.crt
└── ca.key
├── v2/ # After first rotation (Catalyst)
├── ca.crt
└── ca.key
└── v3/ # After second rotation (ML-DSA)
├── ca.crt
└── ca.key

Rotate a CA with new keys and algorithm.

Terminal window
qpki ca rotate [flags]

Flags:

FlagShortDefaultDescription
--ca-dir-d./caCA directory
--profile-PNew profile for rotation (repeatable for multi-profile)
--passphrase-p""Passphrase for new key
--cross-signfalseCross-sign new CA with previous CA
--dry-runfalsePreview rotation plan without executing

Examples:

Terminal window
# Preview rotation plan (dry-run)
qpki ca rotate --ca-dir ./myca --dry-run
qpki ca rotate --ca-dir ./myca --profile hybrid/catalyst/root-ca
qpki ca rotate --ca-dir ./myca --profile ml/root-ca
qpki ca rotate --ca-dir ./myca --profile ec/root-ca --profile ml/root-ca
qpki ca rotate --ca-dir ./myca --profile ml/root-ca --cross-sign

Activate a pending CA version after rotation.

Terminal window
qpki ca activate [flags]

Flags:

FlagShortDefaultDescription
--ca-dir-d./caCA directory
--version-vVersion to activate

Example:

Terminal window
qpki ca activate --ca-dir ./myca --version v2

List all versions of a CA.

Terminal window
qpki ca versions [flags]

Flags:

FlagShortDefaultDescription
--ca-dir-d./caCA directory

Example:

Terminal window
qpki ca versions --ca-dir ./myca

Output:

CA: My Root CA
VERSION STATUS ALGORITHM CREATED
------- ------ --------- -------
v1 archived EC P-384 2025-01-01
v2 archived Catalyst 2025-06-01
v3 active ML-DSA-87 2026-01-01

Cross-signing creates a certificate chain between old and new CA versions, enabling gradual client migration.

┌──────────────────────────────────────────────────────────────────┐
│ CA Rotation with --cross-sign │
├──────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ │
│ │ Old CA v1 │ │
│ │ (EC) │──────────────────┐ │
│ └──────────────┘ │ signs │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ New CA v2 (Catalyst) │ │
│ ├──────────────────────────────────────────────────────────┤ │
│ │ versions/v2/ca.crt (self-signed) │ │
│ │ versions/v2/ca_crosssigned_by_v1.crt (cross-signed) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────┘

When using --cross-sign, the rotation generates two certificates:

FileDescription
versions/<new>/ca.crtSelf-signed certificate (new CA signs itself)
versions/<new>/ca_crosssigned_by_<old>.crtCross-signed certificate (old CA signs new CA’s public key)

This allows:

  • New clients: trust the new CA directly via ca.crt
  • Existing clients: trust the new CA via the cross-signed certificate chain

Usage:

Terminal window
# Without cross-signing (default)
qpki ca rotate --ca-dir ./myca --profile ml/root-ca
qpki ca rotate --ca-dir ./myca --profile ml/root-ca --cross-sign

Create credentials with multiple algorithm profiles from the start:

Terminal window
# Enroll with both EC and ML-DSA
qpki credential enroll --profile ec/tls-server --profile ml/tls-server \
--var cn=server.example.com \
--var dns_names=server.example.com

This creates a credential with two certificates:

  • One EC P-256 certificate
  • One ML-DSA certificate

3.2 credential rotate with Profile Changes

Section titled “3.2 credential rotate with Profile Changes”

Modify algorithm profiles during credential rotation:

Terminal window
# Add a new profile
qpki credential rotate <cred-id> --add-profile ml/tls-client
qpki credential rotate <cred-id> --remove-profile ec/tls-client
qpki credential rotate <cred-id> --profile ml/tls-client

Workflow:

Terminal window
# 1. Rotate with profile changes
qpki credential rotate alice-xxx --add-profile ml/client
# Output: Version v20260105_abc123 (PENDING)
qpki credential activate alice-xxx --version v20260105_abc123
qpki credential versions alice-xxx

4.1 EC → Catalyst → ML-DSA (Full Transition)

Section titled “4.1 EC → Catalyst → ML-DSA (Full Transition)”

The recommended path for organizations needing backward compatibility.

Terminal window
# Phase 1: Start with EC
qpki ca init --profile ec/root-ca --ca-dir ./ca --var cn="My CA"
qpki credential enroll --ca-dir ./ca --cred-dir ./credentials \
--profile ec/tls-server --var cn=server.example.com
qpki ca rotate --ca-dir ./ca --profile hybrid/catalyst/root-ca
qpki ca activate --ca-dir ./ca --version v2
qpki credential rotate server-xxx --ca-dir ./ca --cred-dir ./credentials \
--profile hybrid/catalyst/tls-server
qpki credential activate server-xxx --cred-dir ./credentials --version v2
qpki ca rotate --ca-dir ./ca --profile ml/root-ca
qpki ca activate --ca-dir ./ca --version v3
qpki credential rotate server-xxx --ca-dir ./ca --cred-dir ./credentials \
--profile ml/tls-server
qpki credential activate server-xxx --cred-dir ./credentials --version v3

For environments that can break with legacy clients.

Terminal window
# Phase 1: Start with EC
qpki ca init --profile ec/root-ca --ca-dir ./ca --var cn="My CA"
qpki credential enroll --ca-dir ./ca --cred-dir ./credentials \
--profile ec/tls-server --var cn=server.example.com
qpki ca rotate --ca-dir ./ca --profile ml/root-ca
qpki ca activate --ca-dir ./ca --version v2
qpki credential rotate server-xxx --ca-dir ./ca --cred-dir ./credentials \
--profile ml/tls-server
qpki credential activate server-xxx --cred-dir ./credentials --version v2

4.3 RSA → EC → ML-DSA (Legacy Migration)

Section titled “4.3 RSA → EC → ML-DSA (Legacy Migration)”

For organizations with RSA legacy infrastructure.

Terminal window
# Phase 1: Legacy RSA (existing)
qpki ca init --profile rsa/root-ca --ca-dir ./ca --var cn="Legacy CA"
qpki ca rotate --ca-dir ./ca --profile ec/root-ca
qpki ca activate --ca-dir ./ca --version v2
qpki ca rotate --ca-dir ./ca --profile ml/root-ca
qpki ca activate --ca-dir ./ca --version v3

For organizations already using hybrid certificates.

Terminal window
# Phase 1: Hybrid Catalyst (existing)
qpki ca init --profile hybrid/catalyst/root-ca --ca-dir ./ca --var cn="Hybrid CA"
qpki ca rotate --ca-dir ./ca --profile ml/root-ca
qpki ca activate --ca-dir ./ca --version v2

Run multiple algorithms simultaneously for maximum compatibility.

Terminal window
# Initialize CA with multiple profiles
qpki ca init --profile ec/root-ca --profile ml/root-ca \
--ca-dir ./ca --var cn="Multi-Algorithm CA"
qpki credential enroll --ca-dir ./ca --cred-dir ./credentials \
--profile ec/tls-server --profile ml/tls-server \
--var cn=server.example.com
qpki crl gen --ca-dir ./ca --all

  1. Inventory: List all CAs and credentials
  2. Test: Set up a test environment
  3. Hybrid first: Use Catalyst for gradual migration
  4. Rollback plan: Keep old versions accessible
ComponentMigration Timing
Root CARotate during scheduled maintenance
Issuing CAAfter root CA is stable
Server credentialsAfter issuing CA
Client credentialsLast, with user coordination
Terminal window
# Check CA versions
qpki ca versions --ca-dir ./ca
qpki credential versions <cred-id>
qpki cert verify server.crt --ca ./ca/ca.crt

If issues occur, revert to the previous version:

Terminal window
# Activate previous CA version
qpki ca activate --ca-dir ./ca --version v1
qpki credential activate <cred-id> --version v1

AlgorithmSecurity LevelUse Case
EC P-256~128-bitGeneral purpose
EC P-384~192-bitRoot CAs
RSA-2048~112-bitLegacy compatibility
RSA-4096~140-bitLegacy high-security
AlgorithmNIST LevelUse Case
ML-DSA-44Level 1General purpose
ML-DSA-65Level 3Most applications
ML-DSA-87Level 5Root CAs, high security
SLH-DSALevel 1-5Hash-based fallback
TypeCombinationStandard
CatalystEC + ML-DSAITU-T X.509 9.8
CompositeEC + ML-DSAIETF draft

  • CA - CA operations and certificate issuance
  • Credentials - Credential management
  • Profiles - Certificate profile templates
  • Post-Quantum - PQC and hybrid certificate concepts