Designing Crypto-Agile APIs
Crypto APIs are best practice for implementing crypto-agile best practices.
Hardcoding cryptographic code is a common mistake. Doing so increases the cost associated with quantum migration or incident response in the wake of a deprecated algorithm or vulnerable cryptographic library.
Cryptographic APIs are best practice for minimizing an organization's exposure to the risks of evolving cryptography. However, they have to be carefully designed and implemented to be effective.
What a Good Cryptographic API Looks Like
A cryptographic API should make it quick and easy for an organization to swap algorithms if needed. Some key features include:
Algorithm Agnosticism: While some cryptographic algorithms have standard parameters (like 256-bit keys), others have significant differences. For example, post-quantum cryptography introduces longer keys and digital signatures. A crypto API should include support for variable-length keys, signatures, and ciphertexts.
Backward Readability: A crypto API should prevent an organization from creating additional cryptographic debt by encrypting or hashing data with deprecated algorithms. However, it should offer backward compatibility, allowing data secured under an older algorithm to be decrypted or verified.
Fail Secure: In some cases, applications may try to use unknown or disallowed algorithms. A crypto API should ensure that this fails securely, rather than allowing the use of potentially unsafe algorithms.
Testability: A crypto API is designed to allow cryptographic algorithms to be swapped quickly and easily. It should be possible to test this capability by actually swapping out the algorithms in use.
Core Design Principles of Crypto APIs
Crypto APIs should be designed to enable applications to continue to operate even if cryptographic code is silently changed behind the scenes. Some of the key design principles of these APIs include:
Expose Capabilities: Crypto APIs should expose functions that provide a particular capability without specifying the algorithm in use. For example, an API should offer sign or symmetricEncryption functions, not a function specifying AES encryption.
Policy-Based Selection: A crypto API should standardize algorithm usage across supported applications. For a particular use case, the algorithm should be determined by policy, not the application using it.
Variable-Length Types: Hardcoding variable sizes for cryptographic parameters (keys, signatures, ciphertexts, etc.) means that application logic will need to be rewritten if a significant algorithm change is made. Crypto APIs should expose variable-length types for these parameters so that the same function could be used for an RSA or ML-DSA signature.
Self-Documenting Output: Crypto APIs are designed to swap algorithms without changes to application code. The outputs of these functions should include information that identifies the algorithm, version, and key ID, allowing the verifier to ensure that an approved algorithm is used for decryption or verification.
Pass Keys By Reference: Cryptographic keys should be passed by ID, not the raw bytes. This enables secure storage and algorithm portability.
Fail Secure: Unknown or disallowed algorithms should be explicitly rejected by the crypto API. This prevents an application from silently using and supporting deprecated and potentially insecure algorithms.
Designing Crypto APIs for Algorithmic Transitions
Quantum migration and other incidents may cause an organization to switch its supported algorithms. Some ways that a crypto API can be designed to support this include:
Hybrid and Composite Algorithm Support: During the transition to post-quantum cryptography (PQC), organizations are encouraged to use hybrid algorithms to balance the risks of classical and post-quantum algorithms. Crypto APIs should support these algorithms at the same level as standalone algorithms.
Multi-Read, Single-Write: Backward compatibility requires the ability to decrypt and verify data using previously-supported algorithms. However, all new writes should be performed using the currently-supported algorithm.
Defined Retirement Path: Organizations may add new algorithms over time to support various use cases. The crypto API should have defined paths for retiring old algorithms to limit the growth of the set of supported algorithms over time.
Where Crypto Abstraction Falls Apart
Ideally, crypto APIs abstract away all details of the cryptographic algorithm, enabling applications to interact with various algorithms via the same interface. However, there are a few areas where this abstraction doesn't work, including:
Key Agreement vs. Encapsulation: Traditional Diffie-Hellman is a key agreement protocol that will become obsolete once cryptographically relevant quantum computers (CRQCs) exist. ML-KEM, its replacement, is a key encapsulation mechanism that should be exposed as encapsulate/decapsulate rather than derivation of a shared secret.
Stateful Signature Schemes: Some digital signature schemes, such as LMS and XMSS, require state tracking for signature creation to track which single-use keys have already been used. This breaks the assumption that sign functions are inherently stateless.
Performance: Post-quantum algorithms generally have higher storage requirements than classical ones, and compute time can vary significantly by algorithm. This has impacts on application storage, network bandwidth, and protocol limits.
Common Mistakes in Implementing Crypto-Agile APIs
A crypto API isn't the same as a crypto-agile API. Some common mistakes include:
Algorithm names in exposed functions or enums
Algorithm-specific parameters leaked through interface (IV or key length, etc.)
Fixed-size return types
1:1 wrappers that just rename library calls
Boolean verify results that don't explain the reason for failed verification
Each team developing its own, standalone API
How to Test a Crypto API
Testing a crypto API requires the ability to verify that the tool behaves properly in all potential situations. Some important tests to incorporate include:
Standardized tests that run the same suite against every supported algorithm
Agility tests determining how quickly a very different algorithm (variable key lengths, signature sizes, etc.) can be swapped in without breaking
Negative tests explicitly testing known failure cases (such as CVE-2026-5588, where a verifier accepted an empty digital signature)
Tests with known answers for each implementation
Best Practices for a Crypto API Rollout
Rolling out a new crypto API can be a disruptive process if not handled carefully. Some best practices include:
Define API Use Cases: A crypto API should offer all of the cryptographic capabilities that users need, otherwise they'll directly call cryptographic library functions. Map out use cases in advance to ensure full coverage.
Wrap Existing Libraries: Cryptographic algorithms can be delicate, and writing primitives from scratch can introduce side channel vulnerabilities or other security risks. Wrapping existing libraries helps to avoid these errors and make it easier to determine if the organization is affected in the case of a deprecated algorithm or insecure library.
Build the Policy Layer: In a crypto-agile organization, policy determines algorithm choice for various use cases. Policies should determine supported algorithms and configurations for all of the various use cases.
Migrate By Priority: A cryptographic bill of materials (CBOM) should identify all of an organization's crypto usage and its level of exposure to harvest now, decrypt later (HNDL) attacks. Migration to the API should be performed based on priority to maximize the impact on the organization's cryptographic security posture.
Enforce the Policy: The use of crypto APIs rather than direct library calls must be enforced to be effective. Policy can be enforced using lint rules built into CI/CD pipelines that flag and block code that violates the rules.
Define Ownership: Crypto APIs can easily grow stale or have multiple teams running their own, distinct versions. Ownership of the API should be clearly defined to ensure use of a singular, up-to-date crypto API.
Further Reading
NIST CSWP 39, Considerations for Achieving Crypto Agility: Strategies and Practices — Sections 2.4, 3.2.3, 3.2.4, 3.4.2, 4, 4.1, and 6.6
NIST SP 800-208, Recommendation for Stateful Hash-Based Signature Schemes (LMS and XMSS)
FIPS 203, Module-Lattice-Based Key-Encapsulation Mechanism Standard (ML-KEM)
FIPS 204, Module-Lattice-Based Digital Signature Standard (ML-DSA)
CVE-2026-5588, Bouncy Castle composite signature verifier accepting an empty signature as valid
Why Hardcoding Algorithms in Your Codebase Is a Liability
Crypto Bill of Materials (CBOM), Explained
Building a Crypto-Agility Training Program for Developers
FAQs
Why not just use a well-known library's API directly?
Cryptographic libraries directly expose algorithm-specific functions and interfaces. Calling the library's API directly can still result in hardcoded cryptography that requires application code to be rewritten if cryptographic algorithms change.
Should algorithm choice be changeable at runtime?
While flexibility is critical for crypto-agility, it's generally best to centrally define and enforce algorithm selection within policy. Runtime selection of algorithms from a list of supported algorithms makes it more difficult to determine which algorithms a particular application uses, which can impact the organization's ability to determine the scope and impact of a cryptographic security incident.
Does a crypto API add meaningful performance overhead?
A crypto API is a thin wrapper with minimal logic that sits between the application code and the cryptographic library. In most cases, the performance impact of the API is negligible, but the organization can measure it and act appropriately.
Should we build this internally or adopt an existing framework?
This decision should be based on the organization's needs and whether a framework incorporates all of the core design principles of crypto-agile APIs. Regardless, the crypto API should wrap existing libraries rather than implementing custom cryptographic code.