Cryptographic Agility - Kryptografische Agilität
Cryptographic agility refers to a system’s ability to replace cryptographic algorithms and parameters without making fundamental architectural changes. Cryptographic agility is crucial for the migration to post-quantum cryptography (PQC) and enables a rapid response to algorithm weaknesses (e.g., SHA-1 deprecation, MD5 replacement) without requiring a complete system redesign.
Cryptographic Agility is not a new concept—but it is rarely implemented consistently. The SHA-1 transition took over a decade because systems had SHA-1 hardcoded into them. The MD5 transition took even longer. Now comes the largest cryptographic migration in IT history: post-quantum cryptography. Systems lacking cryptographic agility will take years again. Agile systems switch algorithms in weeks.
Why Cryptographic Agility Matters
Historical algorithm replacements (how long did they take?):
MD5 (1991 → insecure since 2004):
2004: Collision attack published (Wang/Yu)
2008: Flame malware exploits MD5 weakness for code-signing forgery
2012: BSI: MD5 unsuitable for digital signatures
2024: MD5 still active in many legacy systems!
→ 20+ years of migration, still not complete
SHA-1 (1995 → insecure since 2005):
2005: Theoretical attack published (Wang)
2011: NIST: SHA-1 no longer permitted for signatures after 2013
2017: SHAttered – Google demonstrates first practical SHA-1 collision
2023: SHA-1 still active in network devices and legacy protocols
→ 18 years and still in use
RSA 1024-bit:
2010: NIST: RSA-1024 deprecated for signatures
2015: Deadline expired
2026: Still widespread in IoT devices and embedded systems
Post-Quantum (2024 → Migration underway):
2024: NIST adopts FIPS 203/204/205 (ML-KEM, ML-DSA, SLH-DSA)
2030: Quantum computers (of relevant scale) may be available
2026–2030: Critical window for migration
→ Systems WITHOUT cryptographic agility will need another 15+ years!
Conclusion: Cryptographic agility is not optional—it determines
the survivability of a system in the PQC era.
Architectural Patterns for Cryptographic Agility
Pattern 1: Algorithm Abstraction (Code Level)
BAD - Algorithm hardcoded:
# Python:
import hashlib
hash = hashlib.sha256(data).hexdigest() # What if SHA-256 becomes insecure?
BETTER - Abstraction with Interchangeability:
# Python:
HASH_ALGORITHM = os.getenv("HASH_ALGORITHM", "sha256")
def hash_data(data: bytes, algorithm: str = HASH_ALGORITHM) -> str:
h = hashlib.new(algorithm)
h.update(data)
return h.hexdigest()
# Switch to SHA-3: Change ENV variable → no code change!
HASH_ALGORITHM=sha3_256 → Active immediately
Pattern 2: Cryptographic Provider Interface
# Java - Provider pattern:
public interface CryptoProvider {
byte[] encrypt(byte[] plaintext, byte[] key);
byte[] decrypt(byte[] ciphertext, byte[] key);
String getAlgorithmId();
}
public class AES256GCMProvider implements CryptoProvider {
@Override public byte[] encrypt(byte[] plaintext, byte[] key) { ... }
@Override public String getAlgorithmId() { return "AES-256-GCM"; }
}
public class ML_KEMProvider implements CryptoProvider {
@Override public byte[] encrypt(byte[] plaintext, byte[] key) { ... }
@Override public String getAlgorithmId() { return "ML-KEM-768"; }
}
// Change: CryptoProvider provider = new ML_KEMProvider();
// Rest of the code unchanged!
Pattern 3: Algorithm Negotiation (TLS-style)
Client → Server: "I support: AES-256-GCM, ChaCha20-Poly1305, ML-KEM"
Server: "I support: AES-256-GCM, ChaCha20-Poly1305, ML-KEM"
Agreement: "ML-KEM" (best common support)
→ TLS 1.3: exactly this principle!
→ TLS cipher suites: configurable on the server side without client changes
Pattern 4: Key Versioning
# Always version keys and algorithms together:
{
"key_id": "k2026-03",
"algorithm": "ML-KEM-768",
"created": "2026-03-01",
"expires": "2027-03-01",
"key_material": "<encrypted-key>"
}
# Old encrypted data: decrypt using old key + old algorithm
# New data: encrypt using new key + new algorithm
# No big bang migration required!
TLS Configuration for Cryptographic Agility
Nginx - future-proof TLS configuration:
ssl_protocols TLSv1.2 TLSv1.3;
# Prioritize TLS 1.3 - more secure, faster
ssl_ciphers TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-RSA-AES256-GCM-SHA384;
# TLS 1.3 ciphers first, then TLS 1.2 fallback
ssl_prefer_server_ciphers on;
# Server decides (important for agility!)
# Post-Quantum TLS (experimental, OpenSSL 3.5+):
# ssl_ciphers X25519Kyber768Draft00:TLS_AES_256_GCM_SHA384;
# → Hybrid: classic + PQ combined
OpenSSL 3.x provider system:
# Algorithms as loadable providers:
openssl list -providers
# Default provider (classic) + FIPS provider + OQS provider (post-quantum)
# Load OQS (Open Quantum Safe) provider:
openssl speed -provider oqsprovider ml-kem-768
# Tests ML-KEM-768 performance
Crypto Policy in RHEL/Fedora:
# System-wide cryptography policy:
update-crypto-policies --set FIPS
update-crypto-policies --set FUTURE # Stricter algorithms
# Changes TLS defaults for all applications system-wide
# No app-by-app configuration required!
Java Security Properties (JVM-wide):
# $JAVA_HOME/conf/security/java.security
jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, ...
jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1, DSA, ...
# System-wide for all Java applications – one location, all apps
Hybrid Cryptography for PQC Migration
Hybrid approach: Classical + Post-Quantum in parallel (recommendation during transition period):
Why hybrid?
→ PQC algorithms are new: implementation errors possible
→ Classical cryptography: proven, but vulnerable to quantum attacks
→ Hybrid: both secure = combination secure
→ BSI recommendation: Hybrid until PQC is mature enough
TLS 1.3 Hybrid Key Exchange:
# RFC 9370: Multiple Key Shares in TLS
# OpenSSL 3.5+ (experimental):
Client Hello: key_share = [X25519 || ML-KEM-768]
Server Hello: key_share = [X25519 || ML-KEM-768]
# Session Key = SHA256(X25519_shared_secret || ML-KEM_shared_secret)
# Quantum computer must break BOTH → secure!
SSH Hybrid (OpenSSH 9.0+):
# /etc/ssh/sshd_config
KexAlgorithmssntrup761x25519-sha512@openssh.com,curve25519-sha256
# sntrup761 (PQ) + x25519 (classical) hybrid
Signal Protocol (Messenger):
→ PQXDH: Post-Quantum Extended Diffie-Hellman
→ Replaces X3DH with Hybrid (ML-KEM + X25519)
→ Implemented since Signal 2024
Signature Schemes:
# Hybrid Certificates (RFC in development):
# 1 certificate with 2 key pairs: RSA-4096 + ML-DSA-87
# Signature: RSA_sign(ML-DSA_sign(message))
# Both must be broken—neither RSA nor ML-DSA alone is sufficient
Migration Roadmap for Cryptographic Agility:
2024–2025: Inventory
□ Crypto inventory: where is which algorithm used?
□ Record all APIs, protocols, certificates, and key stores
□ Create a "Crypto Bill of Materials"
2025–2027: Hybrid deployment
□ TLS: Enable hybrid key exchange (where supported)
□ Code refactoring: Abstract algorithms
□ Key management: Introduce versioning
2027–2030: PQC migration
□ Certificates: Gradually switch to ML-DSA
□ Key exchange: Fully PQC (after hybrid phase)
□ Long-lived data: Re-encrypt with PQC keys
2030+: Deprecate classical cryptography
□ Disable RSA and ECC for critical systems
□ Retain AES-256/ChaCha20 (symmetric quantum-secure with 128+ bits!)
```</encrypted-key>