Prerequisites
- Target system, dependencies and environment configured.
Usage
Purpose
Every cryptographic algorithm has a shelf life — MD5, SHA-1, RSA-1024, DES were all "fine" once. The systems that handled their retirement gracefully were the ones designed to swap algorithms without a rewrite; the ones that hardcoded a single algorithm faced painful, risky migrations. Crypto-agility is designing so that changing algorithms and keys is a configuration/rollout task, not a re-architecture. This skill covers building that flexibility in from the start.
When to use it
Designing any system that uses cryptography and will live for years (most of them), or reviewing a system for how hard an algorithm migration would be. It's forward-looking — the payoff comes when an algorithm you depend on gets deprecated or broken, which will happen.
Procedure
- Don't hardcode the algorithm — make it a parameter. Design so the algorithm in use is a configurable choice, not baked into the logic. This is the core of agility: you should be able to change from algorithm A to B without rewriting the code that uses it.
- Store the algorithm/version with the data. Tag encrypted data, hashes, and tokens with which algorithm and key produced them (a version identifier,
kid, or algorithm field). Then old data remains decryptable/verifiable with the old algorithm while new data uses the new one — the key to migrating without a flag day:# store: {version: 2, alg: "argon2id", ...} alongside the value
# verify/decrypt using the stored version; write with the current version
- Support side-by-side old and new during migration. Real migrations aren't instant — you need to read old-format data while writing new-format. Design for a transition period where both are valid, and migrate opportunistically (e.g. re-hash a password on next login, re-encrypt data as it's touched or in a background job).
- Design key rotation in from the start (key-management skill) — algorithm changes and key changes use the same versioning machinery; a system built for key rotation is most of the way to algorithm agility.
- Abstract crypto behind an interface so the rest of the code calls "encrypt/verify" without knowing the algorithm, and the implementation can be swapped centrally. Avoid scattering algorithm-specific calls throughout the codebase.
- Keep a migration plan ready — know how you'd move off each algorithm you depend on, so when a deprecation lands (or PQC arrives — see that skill), it's an execution, not a scramble.
Cheatsheet
the reality: every algorithm eventually needs replacing (MD5/SHA1/RSA-1024/DES...)
crypto-agility = swap algorithm/key WITHOUT a rewrite
design principles
[ ] algorithm is a PARAMETER, not hardcoded
[ ] store algorithm/version WITH the data (version id / kid / alg field)
-> old data verifiable with old alg, new data uses new alg
[ ] support OLD + NEW side-by-side during migration (no flag day)
migrate opportunistically: re-hash on login, re-encrypt on touch / background
[ ] design key rotation in from day one (same machinery as alg change)
[ ] abstract crypto behind an interface (swap centrally, not scattered calls)
[ ] keep a migration plan ready for each algorithm you depend on
payoff: when an algorithm is deprecated/broken, it's execution, not re-architecture.
Reading a design
- A hardcoded algorithm with no version stored = a painful, risky migration when that algorithm is deprecated — you can't tell old data from new and can't run both. The anti-pattern crypto-agility prevents.
- Encrypted data / hashes with no algorithm/version tag = you can't migrate incrementally; changing the algorithm means you can't decrypt/verify existing data. Store the version with the data.
- Crypto calls scattered algorithm-specifically across the codebase = a change touches many places and risks inconsistency. Abstract behind an interface.
- No support for reading old while writing new = any migration requires a flag day (re-encrypt everything at once), which is risky and often impractical at scale. Support side-by-side.
- A system that already does key rotation with versioning = most of the agility work is done; algorithm change uses the same mechanism.
- Parameterised algorithm, version-tagged data, side-by-side migration, abstracted interface = agile; algorithm retirement is manageable.
The fix / best practice
- Parameterise the algorithm and store the algorithm/version alongside every encrypted value, hash, and token, so old and new coexist.
- Support reading old-format while writing new-format, and migrate opportunistically (on-access re-encryption/re-hashing, background jobs) rather than in a flag day.
- Abstract cryptography behind an interface so implementations swap centrally.
- Design key rotation in from the start — the same versioning machinery serves algorithm change.
- Maintain migration plans for the algorithms you depend on, so deprecations (and the coming PQC transition) are executed calmly.
Pitfalls
- Hardcoding a single algorithm. It works until the algorithm is broken/deprecated, then the migration is a rewrite. Parameterise from the start.
- Not versioning stored data. Without an algorithm/version tag, you can't distinguish or migrate old data incrementally — a flag-day migration is the only option, and often infeasible.
- Scattered algorithm-specific calls. A change becomes error-prone surgery across the codebase; abstract it.
- Assuming an algorithm is permanent. None are; designing as if the current choice is forever guarantees a painful future migration.
- Ignoring agility until forced. Building it in early is cheap; retrofitting it under the pressure of a deprecation is expensive and risky.
References
- NIST guidance on cryptographic agility and algorithm transitions (SP 800-131A)
- The key-management, password-hashing, and post-quantum-readiness skills (all rely on agility)
- OWASP Cryptographic Storage Cheat Sheet (versioning/migration)
Inputs
- Relevant source code, logs, network traces, or system specifications.
Outputs
- Analysis findings, security audit report, or generated code artifacts.
1---2name: crypto-agility3description: Use when designing systems so cryptographic algorithms and keys can be changed later without a rewrite — because every algorithm eventually needs replacing.4---5678## Prerequisites9- Target system, dependencies and environment configured.1011## Usage12### Purpose1314Every cryptographic algorithm has a shelf life — MD5, SHA-1, RSA-1024, DES were all "fine" once. The systems that handled their retirement gracefully were the ones designed to swap algorithms without a rewrite; the ones that hardcoded a single algorithm faced painful, risky migrations. Crypto-agility is designing so that changing algorithms and keys is a configuration/rollout task, not a re-architecture. This skill covers building that flexibility in from the start.1516### When to use it1718Designing any system that uses cryptography and will live for years (most of them), or reviewing a system for how hard an algorithm migration would be. It's forward-looking — the payoff comes when an algorithm you depend on gets deprecated or broken, which *will* happen.1920### Procedure21221. **Don't hardcode the algorithm — make it a parameter.** Design so the algorithm in use is a configurable choice, not baked into the logic. This is the core of agility: you should be able to change from algorithm A to B without rewriting the code that uses it.232. **Store the algorithm/version with the data.** Tag encrypted data, hashes, and tokens with which algorithm and key produced them (a version identifier, `kid`, or algorithm field). Then old data remains decryptable/verifiable with the old algorithm while new data uses the new one — the key to migrating without a flag day:24 ```25 # store: {version: 2, alg: "argon2id", ...} alongside the value26 # verify/decrypt using the stored version; write with the current version27 ```283. **Support side-by-side old and new during migration.** Real migrations aren't instant — you need to read old-format data while writing new-format. Design for a transition period where both are valid, and migrate opportunistically (e.g. re-hash a password on next login, re-encrypt data as it's touched or in a background job).294. **Design key rotation in from the start** (key-management skill) — algorithm changes and key changes use the same versioning machinery; a system built for key rotation is most of the way to algorithm agility.305. **Abstract crypto behind an interface** so the rest of the code calls "encrypt/verify" without knowing the algorithm, and the implementation can be swapped centrally. Avoid scattering algorithm-specific calls throughout the codebase.316. **Keep a migration plan ready** — know how you'd move off each algorithm you depend on, so when a deprecation lands (or PQC arrives — see that skill), it's an execution, not a scramble.3233### Cheatsheet3435```36the reality: every algorithm eventually needs replacing (MD5/SHA1/RSA-1024/DES...)37crypto-agility = swap algorithm/key WITHOUT a rewrite3839design principles40 [ ] algorithm is a PARAMETER, not hardcoded41 [ ] store algorithm/version WITH the data (version id / kid / alg field)42 -> old data verifiable with old alg, new data uses new alg43 [ ] support OLD + NEW side-by-side during migration (no flag day)44 migrate opportunistically: re-hash on login, re-encrypt on touch / background45 [ ] design key rotation in from day one (same machinery as alg change)46 [ ] abstract crypto behind an interface (swap centrally, not scattered calls)47 [ ] keep a migration plan ready for each algorithm you depend on4849payoff: when an algorithm is deprecated/broken, it's execution, not re-architecture.50```5152### Reading a design5354- **A hardcoded algorithm with no version stored** = a painful, risky migration when that algorithm is deprecated — you can't tell old data from new and can't run both. The anti-pattern crypto-agility prevents.55- **Encrypted data / hashes with no algorithm/version tag** = you can't migrate incrementally; changing the algorithm means you can't decrypt/verify existing data. Store the version with the data.56- **Crypto calls scattered algorithm-specifically across the codebase** = a change touches many places and risks inconsistency. Abstract behind an interface.57- **No support for reading old while writing new** = any migration requires a flag day (re-encrypt everything at once), which is risky and often impractical at scale. Support side-by-side.58- **A system that already does key rotation with versioning** = most of the agility work is done; algorithm change uses the same mechanism.59- **Parameterised algorithm, version-tagged data, side-by-side migration, abstracted interface** = agile; algorithm retirement is manageable.6061### The fix / best practice6263- **Parameterise the algorithm** and store the algorithm/version alongside every encrypted value, hash, and token, so old and new coexist.64- **Support reading old-format while writing new-format**, and migrate opportunistically (on-access re-encryption/re-hashing, background jobs) rather than in a flag day.65- **Abstract cryptography behind an interface** so implementations swap centrally.66- **Design key rotation in from the start** — the same versioning machinery serves algorithm change.67- **Maintain migration plans** for the algorithms you depend on, so deprecations (and the coming PQC transition) are executed calmly.6869### Pitfalls7071- **Hardcoding a single algorithm.** It works until the algorithm is broken/deprecated, then the migration is a rewrite. Parameterise from the start.72- **Not versioning stored data.** Without an algorithm/version tag, you can't distinguish or migrate old data incrementally — a flag-day migration is the only option, and often infeasible.73- **Scattered algorithm-specific calls.** A change becomes error-prone surgery across the codebase; abstract it.74- **Assuming an algorithm is permanent.** None are; designing as if the current choice is forever guarantees a painful future migration.75- **Ignoring agility until forced.** Building it in early is cheap; retrofitting it under the pressure of a deprecation is expensive and risky.7677### References7879- NIST guidance on cryptographic agility and algorithm transitions (SP 800-131A)80- The key-management, password-hashing, and post-quantum-readiness skills (all rely on agility)81- OWASP Cryptographic Storage Cheat Sheet (versioning/migration)8283## Inputs84- Relevant source code, logs, network traces, or system specifications.8586## Outputs87- Analysis findings, security audit report, or generated code artifacts.