On this page
- Quick Reference: A.8.24 in 60 Seconds
- 🚀 Time-Constrained? Start Here
- What the Control Asks For
- Cryptography Fundamentals
- The Cryptographic Policy
- Approved vs. Prohibited Algorithms
- Encryption at Rest
- Encryption in Transit
- Key Management
- Certificate Management
- Database Encryption
- Application Encryption
- Cloud Cryptography
- Container & Kubernetes Encryption
- Quantum-Resistant Cryptography
- Cryptographic Implementation
- Cryptographic Audit & Validation
- Metrics & KPIs
- Tool Comparison
- Implementation Roadmap: 12 Weeks
- Common Audit Failures & Fixes
- Lessons from Public Cryptographic Breaks
- Multi-Framework Mapping
- FAQ
- 📋 Summary Checklist: 48-Hour Quick Start
Quick Reference: A.8.24 in 60 Seconds
| Question | Answer |
|---|---|
| What is it? | A control requiring the use of cryptography to protect the confidentiality, integrity, and authenticity of information. |
| Why does it matter? | Encryption is the last line of defense. If an attacker breaches your network, encryption determines whether they get your data or just noise. |
| Minimum requirement | Cryptographic policy + approved algorithms + encryption at rest + encryption in transit + key management + certificate management. |
| Audit red flag | MD5/SHA-1 in use, no key rotation, self-signed certificates, no HSM, TLS 1.0/1.1, hardcoded keys, no crypto inventory. |
| Quick win | Turn off TLS 1.0/1.1, enable TLS 1.3, scan repositories for hard-coded keys, move keys into a KMS or HSM, and automate certificate renewal (ACME). Build a crypto inventory: you need it for the shrinking certificate lifetimes and for post-quantum migration. |
| Time to implement | 8–12 weeks for full cryptographic transformation. |
| Related controls | A.5.23 (Cloud), A.8.5 (Secure Authentication), A.8.9 (Configuration), A.8.16 (Monitoring), A.8.25 (Secure Development), A.8.28 (Secure Coding) |
| ISO 27002 attributes | Control type: Preventive · Properties: Confidentiality, Integrity, Availability · Concepts: Protect · Capabilities: Secure configuration · Domains: Protection |
🚀 Time-Constrained? Start Here
| Time You Have | What to Read | What You'll Get |
|---|---|---|
| 15 minutes | Quick Reference (Section 1) + Approved vs. Prohibited Algorithms (Section 5) | One-page summary: what to use, what to ban, audit checklist |
| 1 hour | What the Standard Requires (Section 2) + Encryption at Rest (Section 6) + Encryption in Transit (Section 7) | Understand the control and have actionable encryption configs |
| 1 day | Key Management (Section 8) + Certificate Management (Section 9) + Tool Comparison (Section 18) | Build your complete cryptographic infrastructure |
| 1 week | Full guide + Toolkit implementation | Full implementation with HSM, KMS, quantum readiness, and audit readiness |
What the Control Asks For
The Standard Text (ISO 27001:2022)
ISO 27001:2022 Annex A 8.24 asks organizations to define and implement rules for the effective use of cryptography, including key management.
Do you need this control?
A.8.24 is not mandatory in itself: under clause 6.1.3 you include it if your risk assessment calls for it, and record the decision in your Statement of Applicability. Almost every organisation includes it, because encryption protects data in transit and at rest. What varies is the scope of encryption and key management, set by your risk and legal obligations.
ISO 27002:2022 Implementation Guidance (Section 8.24)
ISO 27002:2022 gives guidance in three parts. In our own words:
General rules for using cryptography. Decide and write down:
- a topic-specific policy on cryptography, so that encryption is used where it helps and not misused;
- the protection each class of information needs, which sets the type and strength of algorithm required;
- how cryptography protects information on mobile devices and removable media, and in transit to them;
- your approach to key management, including recovering encrypted information if a key is lost, damaged or compromised;
- who is responsible for applying the rules and for key management, including key generation;
- the approved standards, algorithms, key strengths, products and usage practices;
- the effect encryption has on controls that need to inspect content, such as malware scanning, DLP and web filtering.
Also take into account national laws that restrict cryptography or the movement of encrypted information across borders (see A.5.31), and make sure contracts with crypto service providers, such as certificate authorities, cover liability, reliability and response times (see A.5.22).
Key management. Use agreed standards and secure methods for the whole key life cycle: generating keys, issuing and obtaining certificates, distributing and activating keys, storing them and controlling who can use them, changing them, handling compromised keys, revoking or deactivating them (archiving them when a user leaves), recovering lost keys, backing up and archiving them, destroying them, logging key-management activity, setting activation and deactivation dates, and handling lawful requests for access to keys or decrypted information. Protect all keys against modification and loss, protect secret and private keys against unauthorised use and disclosure, physically protect the equipment that generates and stores keys, and check that public keys are authentic.
Other information. Public-key authenticity is usually handled with certificate authorities and certificates. Cryptography can serve confidentiality (encryption), integrity and authenticity (signatures, MACs, file-integrity checks), non-repudiation, and authentication. The ISO/IEC 11770 series covers key management in more depth.
The rest of this guide shows how to put each of these into practice.
What Changed from ISO 27001:2013
| 2013 Version | 2022 Version | Implication |
|---|---|---|
| A.10.1.1, Policy on the use of cryptographic controls | A.8.24, Use of cryptography | Policy and implementation now sit in one control |
| A.10.1.2, Key management | A.8.24, Use of cryptography | Key management is part of the same control |
| A.14.1.2, Securing application services on public networks | A.8.26, Application security requirements | Not part of 8.24; crypto requirements for applications are set under 8.26 and applied under 8.24 |
Key implication: The 2022 version demands implementation, not just documentation. Auditors now spot-check encryption configurations, key storage locations, and certificate expiry.
What Auditors Actually Check
| Auditor Action | What They Want to See |
|---|---|
| Cryptographic policy review | Signed policy, approved algorithm list, key lifecycle defined |
| Spot-check TLS configuration | TLS 1.3 enabled, no TLS 1.0/1.1, strong cipher suites |
| Key inventory | Where are keys stored? HSM? KMS? Spreadsheets? |
| Certificate expiry scan | No expired certificates, no self-signed certs in production |
| Algorithm audit | No MD5, SHA-1, DES, 3DES, RC4, RSA-1024, DSA in use |
| Database encryption | TDE enabled? Column-level? Application-layer? |
| Cloud encryption | SSE enabled? CMK or provider-managed? BYOK? |
| Key rotation evidence | Show rotation logs, frequency, automated or manual |
| HSM/KMS access logs | Who accessed keys? When? Dual control? |
| Source code scan | No hardcoded keys, no custom crypto, no weak randomness |
| Cryptographic module validation | FIPS 140-2/140-3 validation certificates |
| Post-quantum readiness | Has the organization assessed quantum threats? |
Cryptography Fundamentals
Figure · Matrix
How the options compare: Confidentiality to Authenticity
This section starts from first principles, for readers who are not cryptographers.
The Cryptographic Triad
Cryptography protects three properties:
| Property | Threat | Cryptographic Solution | Example |
|---|---|---|---|
| Confidentiality | Unauthorized reading | Encryption | AES-256-GCM encrypts a database |
| Integrity | Unauthorized modification | Hashing / MAC | SHA-256 HMAC verifies file integrity |
| Authenticity | Impersonation | Digital signatures / PKI | ECDSA P-384 signs a TLS certificate |
Non-repudiation (proof of origin) is achieved by combining authenticity with timestamping and logging.
Symmetric vs. Asymmetric Encryption
| Property | Symmetric | Asymmetric |
|---|---|---|
| Keys | One shared key | Key pair: public + private |
| Speed | Fast (GB/s) | Slow (MB/s) |
| Use case | Bulk data encryption | Key exchange, signatures, certificates |
| Key distribution | Hard (must share secret) | Easy (public key is public) |
| Algorithms | AES, ChaCha20, 3DES (deprecated) | RSA, ECDSA, Ed25519, DH, ECDH |
| Real-world use | Encrypting files, databases, disks | TLS handshakes, code signing, email encryption |
The Hybrid Model: Modern cryptography almost always uses both. Asymmetric encryption encrypts a symmetric key ("key encapsulation"). The symmetric key encrypts the bulk data. This is how TLS 1.3 works.
Block Ciphers vs. Stream Ciphers
| Property | Block Cipher | Stream Cipher |
|---|---|---|
| How it works | Encrypts fixed-size blocks (128 bits) | Encrypts one bit/byte at a time |
| Examples | AES (128-bit blocks), DES, 3DES | ChaCha20, RC4 (deprecated), Salsa20 |
| Modes | CBC, GCM, CTR, ECB (never use ECB) | None, generates keystream |
| Padding | Often required (PKCS#7) | Not required |
| Authentication | GCM provides AEAD; CBC needs separate MAC | Poly1305 provides MAC for ChaCha20 |
| Recommendation | AES-256-GCM for most use cases | ChaCha20-Poly1305 for mobile/embedded |
AEAD (Authenticated Encryption with Associated Data): The gold standard. Provides confidentiality + integrity + authenticity in one operation. Always use AEAD modes when available. AES-256-GCM and ChaCha20-Poly1305 are both AEAD.
Hashing and Digital Signatures
| Algorithm | Type | Status | Use Case |
|---|---|---|---|
| MD5 | Hash | BROKEN: collision attacks in seconds | Never use |
| SHA-1 | Hash | DEPRECATED: collision attacks feasible | Legacy only, migrate immediately |
| SHA-256 | Hash | APPROVED | File integrity, certificate hashing, blockchain |
| SHA-3 (256/512) | Hash | APPROVED | Future-proof hashing, NIST standard |
| BLAKE2b/BLAKE3 | Hash | APPROVED (non-NIST) | High-performance hashing, file verification |
| RSA-1024 | Signature | BROKEN | Never use |
| RSA-2048 | Signature | APPROVED to 2030 (112-bit security) | TLS certificates, general signing; plan post-quantum migration |
| RSA-3072 / RSA-4096 | Signature | APPROVED | Code signing (CA/B Forum requires 3072+), long-lived keys |
| ECDSA P-256 | Signature | APPROVED | TLS, code signing, mobile |
| ECDSA P-384 | Signature | APPROVED | High-security environments, government |
| Ed25519 | Signature | APPROVED | SSH, Git signing, modern protocols |
| DSA | Signature | DEPRECATED | Never use |
Public Key Infrastructure (PKI)
PKI is the system that binds public keys to identities. It consists of:
| Component | Function | Example |
|---|---|---|
| Certificate Authority (CA) | Issues and signs certificates | DigiCert, Let's Encrypt, Sectigo, internal CA |
| Registration Authority (RA) | Validates identity before certificate issuance | Let's Encrypt ACME validation |
| Certificate | Binds public key to identity | TLS certificate for singahi.com |
| Certificate Revocation List (CRL) | Lists revoked certificates | Published by CA |
| OCSP | Online Certificate Status Protocol | Real-time revocation check |
| OCSP Stapling | Server includes OCSP response in TLS handshake | Reduces client latency and privacy leak |
| Certificate Transparency (CT) | Public log of all issued certificates | Google CT logs, crt.sh |
| Trust Store | List of trusted root CAs | Microsoft, Apple, Mozilla, Google trust stores |
Quantum Threats and Post-Quantum Cryptography
The arrival of cryptographically relevant quantum computers (CRQCs) will break:
| Algorithm Class | Broken by Quantum? | Post-Quantum Replacement |
|---|---|---|
| RSA (all key sizes) | ✅ Yes, Shor's algorithm | ML-KEM (FIPS 203) for key establishment; ML-DSA (FIPS 204) or SLH-DSA (FIPS 205) for signatures |
| ECDSA/ECDH (all curves) | ✅ Yes, Shor's algorithm | ML-KEM for key exchange; ML-DSA for signatures |
| DSA/DH | ✅ Yes, Shor's algorithm | ML-KEM / ML-DSA |
| AES-256 | ⚠️ Grover's algorithm halves effective key strength | AES-256 still secure (equivalent to AES-128) |
| SHA-256 | ⚠️ Grover's algorithm reduces preimage strength to about 128 bits | Still considered secure; SHA-384 for long-term use |
| SHA-3 | ⚠️ Same Grover effect as SHA-2 | Remains secure at 256 bits and above |
Timeline: nobody knows when a cryptographically relevant quantum computer will exist. NIST IR 8547 (initial public draft, 2024) proposes deprecating 112-bit classical algorithms such as RSA-2048 after 2030 and disallowing quantum-vulnerable public-key algorithms after 2035. "Harvest now, decrypt later" attacks are happening today. Organizations should begin crypto-agility planning now.
Where to start: build a cryptographic inventory (where RSA, ECDSA and DH are used, by whom, for how long the data must stay secret), then plan a phased migration, using hybrid classical plus post-quantum key exchange first for data that must stay confidential for many years.
Cryptographic Inventory (CBOM) Template
A cryptographic bill of materials (CBOM) is the starting point for post-quantum planning and for coping with shorter certificate lifetimes. One row per use of cryptography:
| Field | Example |
|---|---|
| System / application | Payments API |
| Purpose | TLS to customers; data-at-rest encryption; signing |
| Algorithm and key size | ECDSA P-256; AES-256-GCM |
| Library / product and version | OpenSSL 3.x; cloud KMS |
| Where the key lives | KMS key ID; HSM partition; file path (should not be a file) |
| Key owner | Platform team |
| Certificate issuer and expiry (if any) | Public CA, expires [date] |
| Renewal method | ACME automated / manual |
| How long the protected data must stay secret | 10 years (drives post-quantum priority) |
| Quantum-vulnerable? | Yes (ECDSA) |
| Planned change and date | Hybrid key exchange by [date] |
The Cryptographic Policy
If you select A.8.24, ISO 27002 expects a topic-specific policy on cryptography. Here is a template to adapt.
Cryptographic Policy Template
═══════════════════════════════════════════════════════════════
CRYPTOGRAPHIC POLICY
[Organization Name] — ISO 27001:2022 Annex A 8.24
═══════════════════════════════════════════════════════════════
1. PURPOSE
This policy defines the rules, standards, and procedures for
the use of cryptography to protect the confidentiality,
integrity, and authenticity of organizational information.
2. SCOPE
This policy applies to:
• All information assets classified as Internal, Confidential,
or Highly Confidential
• All data at rest, in transit, and in use (where technically feasible)
• All systems, applications, databases, and cloud services
• All employees, contractors, and third-party suppliers
• All cryptographic keys, certificates, and hardware security modules
3. APPROVED ALGORITHMS (2026-06-15)
3.1 SYMMETRIC ENCRYPTION
| Use Case | Approved Algorithm | Minimum Key Size | Notes |
|----------|-------------------|------------------|-------|
| General purpose | AES-256-GCM | 256 bits | AEAD mode preferred |
| Mobile/embedded | ChaCha20-Poly1305 | 256 bits | AEAD, faster on mobile |
| Legacy compatibility | AES-256-CBC | 256 bits | Only with HMAC-SHA-256 |
3.2 ASYMMETRIC ENCRYPTION / KEY EXCHANGE
| Use Case | Approved Algorithm | Minimum Key Size | Notes |
|----------|-------------------|------------------|-------|
| TLS, certificates | RSA | 2048 bits (3072+ for keys used beyond 2030) | ECDSA preferred for performance |
| TLS, certificates | ECDSA | P-256 or P-384 | Preferred over RSA for performance |
| Modern protocols | Ed25519 | 256 bits | SSH, Git, code signing |
| Key exchange | ECDH | P-384 | Perfect forward secrecy |
| Key exchange | X25519 | 256 bits | Modern, fast, secure |
3.3 HASHING
| Use Case | Approved Algorithm | Minimum Output | Notes |
|----------|-------------------|------------------|-------|
| General integrity | SHA-256 | 256 bits | Default choice |
| High security | SHA-384 | 384 bits | Government, finance |
| Future-proof | SHA-3-256 | 256 bits | NIST standard, quantum-resistant |
| Password hashing | Argon2id | — | Memory-hard, OWASP recommended |
| Password hashing (legacy) | bcrypt | cost ≥ 12 | Only if Argon2id unavailable |
3.4 DIGITAL SIGNATURES
| Use Case | Approved Algorithm | Notes |
|----------|-------------------|-------|
| Code signing | ECDSA P-384, RSA-3072 or RSA-4096 | With timestamping |
| Document signing | ECDSA P-384, Ed25519 | Qualified e-signature where required |
| TLS certificates | ECDSA P-256/P-384, RSA-2048 or larger | SHA-256 or SHA-384 for certificate hash |
| Software updates | Ed25519 | Modern, compact signatures |
4. PROHIBITED ALGORITHMS (Effective Immediately)
• MD5 — cryptographically broken, collisions in seconds
• SHA-1 — deprecated, collision attacks feasible
• DES — 56-bit key, brute-forceable in hours
• 3DES (Triple DES) — vulnerable to Sweet32 attack, deprecated by NIST
• RC4 — broken stream cipher, biases in keystream
• RSA-1024 — factorable with modern hardware
• RSA keys below 2048 bits
• DSA — deprecated by NIST, vulnerable to parameter manipulation
• ECDSA P-192, P-224 — too small, deprecated
(AES-128 remains NIST-approved; this policy standardises on AES-256 for new systems)
• Custom / homegrown cryptography — NEVER
• PKCS#1 v1.5 padding for RSA — use OAEP instead
5. KEY MANAGEMENT REQUIREMENTS
• All keys must be generated using approved CSPRNGs (Cryptographically
Secure Pseudo-Random Number Generators)
• All symmetric keys ≥ 256 bits
• All private keys must be stored in HSM or KMS
• No private keys may be stored in source code, configuration files,
databases, or spreadsheets
• Cryptoperiods are set per key type and risk, using NIST SP 800-57 Part 1;
typically automatic annual rotation for KMS keys, and 1-2 years or
certificate renewal for asymmetric keys
• Every key has activation and deactivation dates in the key register
• Keys of leavers are revoked and, where data depends on them, archived
• Key-management actions are logged and reviewed
• Key-generation and storage equipment (HSMs) is physically protected
• Lawful requests for keys or decrypted data (e.g. under IT Act s.69)
go to Legal and the CISO before any action
• Key destruction: NIST SP 800-88 Rev 2 media sanitisation methods
• Dual control: key generation and deletion requires 2 authorized personnel
• Split knowledge: no single individual knows the complete key
6. CERTIFICATE MANAGEMENT
• All production certificates must be issued by a trusted public CA
or an internal CA with documented trust anchor distribution
• No self-signed certificates in production
• Certificate validity (publicly trusted TLS, CA/Browser Forum Ballot
SC-081): max 200 days from 15 Mar 2026, 100 days from 15 Mar 2027,
47 days from 15 Mar 2029
• Automated renewal (ACME or CA API) is mandatory under this policy;
renew when a third of the lifetime remains
• Contracts with certificate authorities and other crypto service
providers cover liability, reliability and response times
• Certificate Transparency: all certificates must be logged to CT logs
• Revocation: OCSP must be enabled; OCSP stapling preferred
• Monitoring: certificate expiry must be monitored with ≤ 14-day alerts
7. ENCRYPTION AT REST REQUIREMENTS
• All laptops and desktops: Full Disk Encryption (BitLocker, FileVault, LUKS)
• All mobile devices: AES-256 (built-in or enforced via MDM)
• All databases: TDE or application-layer encryption
• All file servers: volume-level encryption
• All backup media: encrypted before leaving production environment
• All cloud storage: SSE with customer-managed keys (CMK) or higher
8. ENCRYPTION IN TRANSIT REQUIREMENTS
• TLS 1.3 is mandatory for all external-facing services
• TLS 1.2 is the minimum for internal services (with strong cipher suites)
• TLS 1.0 and 1.1 are prohibited
• Weak cipher suites are prohibited (see Appendix A)
• Certificate pinning for mobile applications
• Mutual TLS (mTLS) for service-to-service communication in microservices
• VPN: IPsec or WireGuard for site-to-site; WireGuard or OpenVPN for remote
• Where TLS inspection is needed for malware scanning, DLP or web
filtering, it is documented, approved and excludes sensitive categories
(e.g. banking and health sites)
9. IMPLEMENTATION GUIDE
• All new systems must use approved algorithms from day one
• All legacy systems must be inventoried and migrated within 12 months
• Cryptographic implementations must use validated libraries only
(OpenSSL 3.x, BoringSSL, libsodium, AWS Encryption SDK, Tink)
• All code must be reviewed for hardcoded keys and weak algorithms
• Annual cryptographic review by qualified cryptographer or third party
• Post-quantum readiness assessment by 2027
10. COMPLIANCE AND GOVERNANCE
• CISO owns this policy
• Crypto Council reviews annually (Security, Engineering, Compliance, Architecture)
• Violations are treated as security incidents
• Non-compliance blocks production deployment
11. APPENDIX A: APPROVED TLS 1.3 CIPHER SUITES
• TLS_AES_256_GCM_SHA384
• TLS_CHACHA20_POLY1305_SHA256
• TLS_AES_128_GCM_SHA256 (legacy compatibility only)
12. APPENDIX B: APPROVED TLS 1.2 CIPHER SUITES (Internal Only)
• TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
• TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
• TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
• TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
• TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (legacy)
• TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (legacy)
13. APPENDIX C: KEY LIFECYCLE
[See Section 8: Key Management]
Approved by: _________________________ Date: _______________
Review Date: _________________________ Version: _______________
Approved vs. Prohibited Algorithms
This is the most important section for audit readiness. Get this wrong, and you fail.
Approved Algorithm Reference Table
| Category | Algorithm | Status | Key Size / Parameters | Use Cases |
|---|---|---|---|---|
| Symmetric Encryption | AES-256-GCM | ✅ APPROVED | 256-bit key, 96-bit nonce | General purpose, databases, files, TLS |
| Symmetric Encryption | ChaCha20-Poly1305 | ✅ APPROVED | 256-bit key | Mobile, embedded, TLS, disk encryption |
| Symmetric Encryption | AES-256-CBC | ⚠️ LEGACY ONLY | 256-bit key + HMAC | Legacy systems only; migrate to GCM |
| Asymmetric Encryption | RSA-3072 / RSA-4096 | ✅ APPROVED | 3072+ bit key | Code signing, long-lived keys |
| Asymmetric Encryption | RSA-2048 | ✅ APPROVED to 2030 | 2048-bit key | TLS certificates; plan post-quantum migration |
| Asymmetric Encryption | ECDSA P-384 | ✅ APPROVED | NIST P-384 curve | TLS, certificates, high-security |
| Asymmetric Encryption | ECDSA P-256 | ✅ APPROVED | NIST P-256 curve | TLS, mobile, constrained devices |
| Asymmetric Encryption | Ed25519 | ✅ APPROVED | 256-bit | SSH, Git, modern protocols |
| Asymmetric Encryption | X25519 | ✅ APPROVED | 256-bit | Key exchange, TLS 1.3 |
| Hashing | SHA-256 | ✅ APPROVED | 256-bit output | File integrity, certificates, blockchain |
| Hashing | SHA-384 | ✅ APPROVED | 384-bit output | High-security, government |
| Hashing | SHA-512 | ✅ APPROVED | 512-bit output | Long-term integrity |
| Hashing | SHA-3-256 | ✅ APPROVED | 256-bit output | Alternative to SHA-256 |
| Hashing | SHA-3-512 | ✅ APPROVED | 512-bit output | Future-proof, high-security |
| Hashing | BLAKE2b | ✅ APPROVED | Variable output | High-performance, non-NIST alternative |
| Password Hashing | Argon2id | ✅ APPROVED | Memory ≥ 64 MB, iterations ≥ 3 | Password storage, OWASP recommended |
| Password Hashing | bcrypt | ⚠️ LEGACY | cost ≥ 12 | If Argon2id unavailable |
| Password Hashing | scrypt | ⚠️ LEGACY | N=2^20, r=8, p=1 | If Argon2id unavailable |
| Password Hashing | PBKDF2 | ⚠️ LEGACY | 600,000+ iterations | Only for FIPS compliance; Argon2id preferred |
| Key Derivation | HKDF (SHA-256/384) | ✅ APPROVED | Extract-then-expand | TLS 1.3, key derivation from secrets |
| Key Derivation | PBKDF2 (legacy) | ⚠️ LEGACY | 600,000+ iterations | Legacy compatibility |
| Digital Signature | ECDSA P-384 + SHA-384 | ✅ APPROVED | P-384 curve | Code signing, certificates, documents |
| Digital Signature | RSA-3072+ with SHA-256/384 | ✅ APPROVED | 3072-bit RSA or larger | Code signing, certificates, email |
| Digital Signature | Ed25519 | ✅ APPROVED | 256-bit | SSH, Git, software updates |
| MAC | HMAC-SHA-256 | ✅ APPROVED | 256-bit key | Message authentication |
| MAC | HMAC-SHA-384 | ✅ APPROVED | 384-bit key | High-security authentication |
| MAC | AES-GMAC | ✅ APPROVED | 256-bit key | AES-based MAC (use GCM instead) |
| Random Number | /dev/urandom, getrandom() | ✅ APPROVED | CSPRNG | Key generation, nonce generation |
| Random Number | OpenSSL RAND_bytes | ✅ APPROVED | CSPRNG | Application-level randomness |
| Random Number | libsodium randombytes | ✅ APPROVED | CSPRNG | Modern applications |
| Random Number | Math.random(), rand() | ❌ PROHIBITED | Deterministic | Never use for cryptography |
| Random Number | java.util.Random | ❌ PROHIBITED | Deterministic | Never use for cryptography |
Prohibited Algorithm Reference Table
| Algorithm | Why Prohibited | CVE / Attack | Migration Path |
|---|---|---|---|
| MD5 | Collision attacks in seconds | CVE-2004-2761, Flame malware | SHA-256, SHA-3 |
| SHA-1 | Collision attacks feasible | SHAttered (2017), chosen-prefix collision (2020) | SHA-256, SHA-3 |
| DES | 56-bit key, brute-forced in 22 hours | DES Cracker (1998) | AES-256-GCM |
| 3DES (Triple DES) | Sweet32 attack, 64-bit block size | CVE-2016-2183 | AES-256-GCM |
| RC4 | Biases in keystream, statistical attacks | Bar Mitzvah attack, RC4 NOMORE | ChaCha20-Poly1305 |
| RSA-1024 and smaller | Factorable; disallowed by NIST SP 800-131A | RSA-768 factored in 2009 | RSA-2048+, ECDSA P-256+ |
| DSA | No longer approved for signature generation (FIPS 186-5) | Nonce-reuse key recovery | ECDSA, Ed25519 |
| ECDSA P-192 / P-224 | Too small, deprecated by NIST | Brute-forceable | ECDSA P-384 |
| Custom / Homegrown Crypto | Inevitably broken | Infinite examples | Use approved libraries |
| PKCS#1 v1.5 (RSA) | Vulnerable to Bleichenbacher attacks | ROBOT attack | RSA-OAEP |
| ECB mode (AES) | Leaks pattern information | Penguin image demo | GCM, CBC with random IV |
| CBC mode without HMAC | Padding oracle attacks | POODLE, Lucky 13 | GCM or CBC + HMAC |
| SSLv2, SSLv3, TLS 1.0, TLS 1.1 | Multiple vulnerabilities | POODLE, BEAST, CRIME | TLS 1.3 |
| DH (Diffie-Hellman) < 2048 bits | Logjam attack | CVE-2015-4000 | ECDH P-384 |
| MD5-based HMAC | Weak collision resistance | Extension attacks | HMAC-SHA-256 |
Algorithm Selection Decision Tree
What do you need to protect?
├── Data at rest (files, databases, disks)
│ ├── General purpose → AES-256-GCM
│ ├── Mobile/embedded → ChaCha20-Poly1305
│ └── Legacy system → AES-256-CBC + HMAC-SHA-256 (migrate plan)
├── Data in transit (network, TLS, VPN)
│ ├── TLS 1.3 → AES-256-GCM or ChaCha20-Poly1305
│ ├── TLS 1.2 (legacy) → AES-256-GCM + ECDHE
│ └── VPN → ChaCha20-Poly1305 (WireGuard) or AES-256-GCM (IPsec)
├── Digital signatures
│ ├── General purpose → ECDSA P-384 or Ed25519
│ ├── Legacy compatibility → RSA-2048+ with SHA-256 (3072+ for long-lived keys)
│ └── Code signing → Ed25519 or ECDSA P-384 + timestamping
├── Key exchange
│ ├── Modern → X25519 or ECDH P-384
│ └── Legacy → RSA key transport (no forward secrecy, avoid)
├── Password hashing
│ ├── Modern → Argon2id (memory ≥ 64MB, iterations ≥ 3, parallelism ≥ 1)
│ ├── Legacy FIPS → PBKDF2-SHA-256 (600,000+ iterations)
│ └── Compatibility → bcrypt (cost ≥ 12)
├── Hashing / integrity
│ ├── General → SHA-256
│ ├── High security → SHA-384 or SHA-512
│ └── Long-term integrity → SHA-384, SHA-512 or SHA-3
└── Random numbers
├── Linux → getrandom() or /dev/urandom
├── Modern app → libsodium randombytes_buf()
└── Legacy → OpenSSL RAND_bytes()
💡 Practitioner tip: A very common algorithm violation is SHA-1 in certificate chains and MD5 in legacy file integrity checks. Run
openssl s_client -connect your-site:443 | openssl x509 -text | grep Signature Algorithmtoday. If you seesha1WithRSAEncryption, you have an audit finding.
Encryption at Rest
Encryption at rest protects data when storage media is compromised: stolen laptop, breached database, exposed S3 bucket. It is the control of last resort.
Full Disk Encryption (FDE)
| Platform | Tool | Algorithm | Key Management | Configuration |
|---|---|---|---|---|
| Windows 10/11 | BitLocker | AES-256-XTS | TPM 2.0 + PIN + AD/Entra ID escrow | Group Policy / Intune |
| macOS | FileVault 2 | AES-256-XTS | Institutional recovery key via MDM | Jamf / MDM profile |
| Linux | LUKS (dm-crypt) | AES-256-XTS | Passphrase + key file + LUKS header backup | cryptsetup |
| iOS | Built-in | AES-256 (hardware) | Secure Enclave + Apple ID | Automatic |
| Android | File-Based Encryption (FBE) | AES-256-XTS | TEE / StrongBox | Android Enterprise |
BitLocker Deep Configuration:
## Require TPM + PIN + Recovery Key
## Computer Configuration > Policies > Windows Components > BitLocker
## Enable BitLocker with TPM + PIN
manage-bde -on C: -recoverypassword -tpmandpin
## Set minimum PIN length to 6 digits
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\FVE" -Name "MinimumPIN" -Value 6
## Require startup PIN with TPM
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\FVE" -Name "UseTPMPIN" -Value 1
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\FVE" -Name "UseAdvancedStartup" -Value 1
## Escrow recovery key to Active Directory / Entra ID
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\FVE" -Name "OSRecovery" -Value 1
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\FVE" -Name "OSActiveDirectoryBackup" -Value 1
## Encrypt data drives too
manage-bde -on D: -recoverypassword -password
## Verify status
manage-bde -status C:
LUKS Deep Configuration (Linux):
## Create LUKS container with AES-256-XTS
sudo cryptsetup luksFormat --type luks2 --cipher aes-xts-plain64 \
--key-size 512 --hash sha512 --pbkdf argon2id \
--iter-time 5000 /dev/nvme0n1p2
## Open the container
sudo cryptsetup open /dev/nvme0n1p2 cryptroot
## Create filesystem
sudo mkfs.ext4 /dev/mapper/cryptroot
## Backup LUKS header (CRITICAL — without this, data is unrecoverable if header corrupts)
sudo cryptsetup luksHeaderBackup /dev/nvme0n1p2 \
## Store backup in HSM-protected storage or offline secure vault
## Verify encryption status
lsblk -f
## Should show: crypto_LUKS type
## Add a secondary key slot (for key escrow / dual control)
sudo cryptsetup luksAddKey /dev/nvme0n1p2
Database Encryption
| Database | TDE Support | Algorithm | Key Management | Configuration |
|---|---|---|---|---|
| MySQL 8.0+ | InnoDB TDE | AES-256-CBC | Keyring plugin (file, AWS KMS, HashiCorp Vault) | innodb_encrypt_tables=ON |
| PostgreSQL 15+ | pg_crypto (extension) | AES-256 | pgcrypto + external KMS | encrypt(data, key, 'aes-256-cbc') |
| PostgreSQL 16+ | TDE (EnterpriseDB, CloudNativePG) | AES-256 | External KMS | CloudNativePG cluster spec |
| SQL Server 2022 | TDE | AES-256 | SQL Server KMS, Azure Key Vault | CREATE DATABASE ENCRYPTION KEY |
| Oracle 23c | TDE | AES-256 | Oracle Wallet, HSM, AWS KMS | ALTER SYSTEM SET TDE_KEYSTORE=OKS |
| MongoDB 7.0+ | Encryption at Rest | AES-256-GCM | MongoDB KMS, AWS KMS, Azure Key Vault | security.enableEncryption: true |
| Redis 7.0+ | No native TDE | AES-256 (application layer) | Application KMS | Client-side encryption |
| Elasticsearch 8.x | TDE (X-Pack) | AES-256 | Keystore + external KMS | xpack.security.encryption |
| Cassandra 4.1+ | TDE | AES-256 | JKS + external KMS | system_properties config |
| CockroachDB | Encryption at Rest | AES-128-GCM (default) | Store key files in KMS | --enterprise-encryption |
SQL Server TDE Implementation:
-- Step 1: Create master key (protected by password — store in vault)
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'StrongPasswordFromVault';
-- Step 2: Create certificate for TDE
CREATE CERTIFICATE TDE_Certificate
WITH SUBJECT = 'TDE Certificate for Production DBs';
-- Step 3: Create database encryption key
CREATE DATABASE ENCRYPTION KEY
WITH ALGORITHM = AES_256
ENCRYPTION BY SERVER CERTIFICATE TDE_Certificate;
-- Step 4: Enable TDE on database
ALTER DATABASE ProductionDB
SET ENCRYPTION ON;
-- Step 5: Verify encryption status
SELECT db.name, db.is_encrypted, dm.encryption_state, dm.percent_complete
FROM sys.databases db
LEFT JOIN sys.dm_database_encryption_keys dm
ON db.database_id = dm.database_id
WHERE db.name = 'ProductionDB';
-- encryption_state: 0 = No database encryption key present
-- 1 = Unencrypted
-- 2 = Encryption in progress
-- 3 = Encrypted
-- 4 = Key change in progress
-- 5 = Decryption in progress
-- 6 = Protection change in progress
MongoDB Encryption at Rest:
## mongod.conf for encryption at rest
security:
enableEncryption: true
encryptionCipherMode: AES256-GCM
encryptionKeyFile: /etc/mongodb-keyfile
# Or use KMIP for external KMS:
kmip:
serverName: kmip.example.com
port: 5696
clientCertificateFile: /etc/mongodb-kmip-client.pem
serverCAFile: /etc/mongodb-kmip-ca.pem
File Encryption
| Tool | Algorithm | Use Case | Platform |
|---|---|---|---|
| EFS (Windows) | AES-256 | File-level encryption in NTFS | Windows |
| VeraCrypt | AES-256, Serpent, Twofish | Container encryption, hidden volumes | Cross-platform |
| 7-Zip | AES-256 | Archive encryption | Cross-platform |
| GnuPG (GPG) | AES-256, RSA-4096 | File signing and encryption | Cross-platform |
| age | X25519 + ChaCha20-Poly1305 | Modern file encryption | Cross-platform |
| OpenSSL | AES-256-GCM | Command-line encryption | Cross-platform |
Cloud Storage Encryption
| Cloud | Service | Default Encryption | Customer-Managed Key | Client-Side Encryption |
|---|---|---|---|---|
| AWS | S3 | SSE-S3 (AES-256) | SSE-KMS (AWS KMS) | SSE-C or client-side |
| AWS | EBS | AES-256 | KMS | Application-layer |
| AWS | RDS | AES-256 | KMS | Application-layer |
| Azure | Blob Storage | SSE (AES-256) | Customer-managed key (Key Vault) | Client-side SDK |
| Azure | Managed Disks | SSE (AES-256) | Key Vault | N/A |
| Azure | SQL Database | TDE (AES-256) | Key Vault | Always Encrypted |
| GCP | Cloud Storage | AES-256 | Cloud KMS | Client-side |
| GCP | Persistent Disk | AES-256 | Cloud KMS | Application-layer |
| GCP | Cloud SQL | AES-256 | Cloud KMS | Application-layer |
| Oracle Cloud | Object Storage | AES-256 | Vault KMS | Client-side |
| IBM Cloud | Cloud Object Storage | AES-256 | Key Protect | Client-side |
AWS S3 Encryption Configuration:
{
"Rules": [
{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
},
"BucketKeyEnabled": true
}
]
}
Key Management for At-Rest Encryption:
| Storage Layer | Key Management Approach | Best Practice |
|---|---|---|
| Laptop/desktop FDE | TPM + PIN + AD/MDM escrow | Recovery keys in HSM-backed vault |
| Database TDE | Database KMS plugin or external HSM | Rotate the protector key on a risk-based schedule; KEK in HSM |
| File encryption | User-managed passphrase or organizational KMS | Passphrase minimum 16 characters; use Argon2id |
| Cloud storage | Cloud KMS with customer-managed keys (CMK) | Enable key rotation; use separate keys per environment |
| Backup encryption | HSM or offline KMS with key escrow | Test restore annually; keep escrowed keys for as long as the backups they protect |
📊 Practitioner insight: A typical failure: TDE enabled on SQL Server but the TDE certificate was stored in a shared network folder with no access controls. The encryption was technically "on" but the key was trivially accessible. Encryption without key protection is theater. Always store keys in HSM or KMS, never alongside the data.
Encryption in Transit
Encryption in transit protects data as it moves across networks. The standard is TLS 1.3. Everything else is legacy.
TLS 1.3 Deep Dive
TLS 1.3 (RFC 8446) is a radical simplification of TLS 1.2. It removes obsolete features and mandates modern cryptography.
| Feature | TLS 1.2 | TLS 1.3 | Why It Matters |
|---|---|---|---|
| Handshake RTT | 2-RTT | 1-RTT (0-RTT with resumption) | Faster connections, better UX |
| Cipher suites | 37+ combinations | 5 AEAD suites only | Simpler, more secure |
| Key exchange | RSA, DH, ECDH (many options) | ECDHE only | Perfect forward secrecy mandatory |
| Signature algorithms | MD5, SHA-1, SHA-256 | SHA-256+ only | No weak algorithms |
| Compression | Supported | Removed | CRIME attack eliminated |
| Renegotiation | Supported | Removed | Renegotiation attacks eliminated |
| Custom DHE groups | Supported | Removed | Logjam attack eliminated |
| Encrypt-then-MAC | Optional | Always | Proper AEAD |
| Record padding | Not supported | Supported | Traffic analysis resistance |
| Obsolete algorithms | RC4, 3DES, DES, EXPORT | All removed | No downgrade attacks |
TLS 1.3 Cipher Suites (Approved Only):
| Cipher Suite | Algorithm | Hash | Use Case |
|---|---|---|---|
TLS_AES_256_GCM_SHA384 | AES-256-GCM | SHA-384 | Default, high security |
TLS_CHACHA20_POLY1305_SHA256 | ChaCha20-Poly1305 | SHA-256 | Mobile, low-power devices |
TLS_AES_128_GCM_SHA256 | AES-128-GCM | SHA-256 | Legacy compatibility only |
TLS 1.3 Configuration (nginx):
server {
listen 443 ssl http2;
server_name singahi.com;
ssl_certificate /etc/ssl/certs/singahi.crt;
ssl_certificate_key /etc/ssl/private/singahi.key;
# TLS 1.3 only (production)
ssl_protocols TLSv1.3;
# If legacy compatibility needed, add TLS 1.2 with strict cipher list
# ssl_protocols TLSv1.3 TLSv1.2;
# TLS 1.3 cipher suites (order matters)
ssl_ciphers TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;
# For TLS 1.2 compatibility (if enabled)
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
# Prefer server cipher order
ssl_prefer_server_ciphers on;
# Elliptic curves
ssl_ecdh_curve X25519:P-384:P-256;
# Session configuration
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off; # Disable for forward secrecy
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/ssl/certs/chain.crt;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# HSTS (preload recommended)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# Certificate Transparency
add_header Expect-CT "max-age=86400, enforce" always;
}
TLS 1.3 Configuration (Apache):
<VirtualHost *:443>
ServerName singahi.com
SSLEngine on
SSLCertificateFile /etc/ssl/certs/singahi.crt
SSLCertificateKeyFile /etc/ssl/private/singahi.key
SSLCertificateChainFile /etc/ssl/certs/chain.crt
# TLS 1.3 only
SSLProtocol -all +TLSv1.3
# TLS 1.3 cipher suites
SSLCipherSuite TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
# For TLS 1.2 compatibility
# SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
SSLHonorCipherOrder on
# OCSP Stapling
SSLUseStapling on
SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
# HSTS
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
# Certificate Transparency
Header always set Expect-CT "max-age=86400, enforce"
</VirtualHost>
Certificate Pinning
Certificate pinning binds an application to a specific certificate or public key, preventing MITM attacks even if a rogue CA issues a fraudulent certificate.
| Pinning Type | How It Works | Risk | Use Case |
|---|---|---|---|
| Static pinning | Hardcode certificate hash in app | App breaks if cert changes | Mobile apps with long update cycles |
| Dynamic pinning | Pin first-seen certificate | Vulnerable on first connection | Better than nothing |
| TACK / HPKP | HTTP Public Key Pinning (deprecated) | High risk of bricking sites | Deprecated, do not use |
| DANE (DNSSEC) | TLSA record in DNS | Requires DNSSEC deployment | Enterprise, DNSSEC-enabled zones |
| CT monitoring | Monitor Certificate Transparency logs | Detects unauthorized certs | All organizations |
Mobile App Certificate Pinning (Android, okhttp):
val certificatePinner = CertificatePinner.Builder()
.add("singahi.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
.add("singahi.com", "sha256/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=")
.build()
val client = OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build()
Mobile App Certificate Pinning (iOS, Alamofire):
let serverTrustManager = ServerTrustManager(evaluators: [
"singahi.com": PinnedCertificatesTrustEvaluator(
certificates: [certData],
acceptSelfSignedCertificates: false,
performDefaultValidation: true,
validateHost: true
)
])
Mutual TLS (mTLS)
mTLS authenticates both client and server. Essential for microservices, APIs, and Zero Trust architectures.
| Use Case | Client Certificate | Server Certificate | Why mTLS |
|---|---|---|---|
| Microservices | Service identity cert | Service identity cert | No network trust assumptions |
| API access | Client cert per integration partner | API gateway cert | Stronger than API keys |
| IoT devices | Device identity cert | Cloud platform cert | No passwords to steal |
| Database access | Application cert | Database cert | Stronger than password + IP whitelist |
| Employee VPN | User cert + MFA | VPN gateway cert | Phishing-resistant remote access |
mTLS Configuration (nginx):
server {
listen 443 ssl;
server_name api.singahi.com;
ssl_certificate /etc/ssl/certs/api.crt;
ssl_certificate_key /etc/ssl/private/api.key;
# Require client certificate
ssl_client_certificate /etc/ssl/certs/ca.crt;
ssl_verify_client on;
ssl_verify_depth 2;
location / {
# Pass client certificate info to upstream
proxy_pass http://backend;
}
}
VPN Protocols
| Protocol | Encryption | Authentication | Key Exchange | Best For |
|---|---|---|---|---|
| WireGuard | ChaCha20-Poly1305 | Curve25519 | ECDH (X25519) | Modern remote access, site-to-site, mobile |
| IPsec (IKEv2) | AES-256-GCM | ECDSA P-384 / RSA-4096 | ECDH | Enterprise site-to-site, high compliance |
| OpenVPN | AES-256-GCM | TLS 1.3 / certificates | TLS handshake | Flexibility, legacy support |
| TLS VPN | TLS 1.3 | Certificates | TLS 1.3 | Browser-based access |
WireGuard Configuration:
## /etc/wireguard/wg0.conf — Server
[Interface]
PrivateKey = <server-private-key>
Address = 10.0.0.1/24
ListenPort = 51820
## Firewall rules
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
## Client 1
PublicKey = <client1-public-key>
AllowedIPs = 10.0.0.2/32
[Peer]
## Client 2
PublicKey = <client2-public-key>
AllowedIPs = 10.0.0.3/32
SSH Hardening
SSH is the most common remote administration protocol. Weak SSH configuration is a major audit finding.
## /etc/ssh/sshd_config — Hardened Configuration
## Protocol and algorithms
Protocol 2
KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp384
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
## Authentication
PasswordAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey
PermitRootLogin no
MaxAuthTries 3
MaxSessions 2
LoginGraceTime 30
## Host keys
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_ecdsa_key
## Key requirements
PubkeyAcceptedAlgorithms ssh-ed25519,ecdsa-sha2-nistp384,rsa-sha2-512
## Connection hardening
ClientAliveInterval 300
ClientAliveCountMax 2
TCPKeepAlive no
AllowUsers admin@10.0.0.* deploy@10.0.0.*
AllowGroups ssh-users
## Logging
LogLevel VERBOSE
SyslogFacility AUTH
Email Encryption: S/MIME and PGP
| Protocol | Standard | Key Management | Use Case | Ease of Use |
|---|---|---|---|---|
| S/MIME | RFC 5751 | Certificate-based (X.509) | Enterprise email | High (built into Outlook, Apple Mail) |
| OpenPGP | RFC 4880 | Web of Trust / key servers | Personal, developer, activist | Medium (requires key management) |
| Autocrypt | Level 1 | Opportunistic encryption | Mobile email | High (automatic) |
| MLS (Messaging Layer Security) | RFC 9420 | Group encryption | Enterprise messaging | Medium (emerging) |
💡 Practitioner tip: We see organizations enable TLS 1.3 on their web servers but forget about internal APIs, database connections, and message queues. Every network connection that carries data must be encrypted. Run
nmap --script ssl-enum-ciphers -p 443,636,993,995,8443 your-domainto find weak TLS across all ports.
Key Management
Key management is the most critical and most failed aspect of cryptography. A stolen key renders all encryption useless. ISO 27001:2022 A.8.24 auditors spend more time on key management than on any other crypto topic.
The Key Lifecycle
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ GENERATION │───▶│ REGISTRATION│───▶│ STORAGE │───▶│ USE │───▶│ ROTATION │───▶│ DESTRUCTION│
│ │ │ │ │ │ │ │ │ │ │ │
│ CSPRNG │ │ KMS catalog │ │ HSM / KMS │ │ Encryption│ │ New key │ │ NIST 800-88 │
│ HSM ceremony│ │ Metadata │ │ Vault │ │ Decryption│ │ Re-encrypt │ │ Purge │
│ Dual control│ │ Access rules │ │ Offline backup│ │ Signing │ │ Old key │ │ Audit log │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
Key Generation
| Key Type | Generation Method | Minimum Entropy | Tool / Command |
|---|---|---|---|
| Symmetric (AES) | CSPRNG | 256 bits | openssl rand -base64 32 |
| RSA key pair | CSPRNG + prime generation | 4096 bits | openssl genrsa -aes256 4096 |
| ECDSA key pair | CSPRNG + curve point | P-384 | openssl ecparam -genkey -name secp384r1 |
| Ed25519 key pair | CSPRNG + clamping | 256 bits | openssl genpkey -algorithm ed25519 |
| X25519 key pair | CSPRNG + clamping | 256 bits | openssl genpkey -algorithm x25519 |
| Password hash salt | CSPRNG | 128 bits | randombytes_buf(16) (libsodium) |
Key Generation Best Practices:
- Generate all keys in HSM or secure enclave when possible
- Use dual control: two authorized personnel present for key generation
- Record key generation in tamper-evident log
- Generate key and backup key simultaneously (for escrow)
- Test key immediately after generation (encrypt/decrypt round-trip)
- Never generate keys on shared or multi-tenant infrastructure without isolation
- Use hardware RNG (HRNG) when available, not software RNG alone
Key Storage
| Storage Location | Security Level | Use Case | Risk |
|---|---|---|---|
| HSM (Hardware Security Module) | ★★★★★ | Production keys, root CA keys, signing keys | Very high cost, vendor lock-in |
| Cloud HSM (AWS CloudHSM, Azure Dedicated HSM, GCP HSM) | ★★★★★ | Cloud-native production keys | Complex setup, cost |
| KMS (AWS KMS, Azure Key Vault, GCP KMS) | ★★★★☆ | Most cloud encryption use cases | Cloud provider trust, API availability |
| HashiCorp Vault | ★★★★☆ | Hybrid, multi-cloud, on-premises | Self-managed complexity |
| Software TPM / TEE | ★★★☆☆ | Mobile, IoT, edge devices | Limited key capacity, extraction risk |
| Encrypted file on disk | ★★☆☆☆ | Development, testing only | Key escrow problem, file system access |
| Environment variable / config file | ★☆☆☆☆ | Never for production | Audit failure, source code exposure |
| Database / spreadsheet | ☆☆☆☆☆ | Never | Immediate audit failure |
| Hardcoded in source code | ☆☆☆☆☆ | Never | Immediate audit failure, security incident |
Hardware Security Modules (HSMs)
HSMs are tamper-resistant hardware devices that generate, store, and manage cryptographic keys. They are the gold standard for key protection.
| HSM Vendor | Model | FIPS 140-2/3 Level | Form Factor | Key Capacity | Best For |
|---|---|---|---|---|---|
| Thales Luna 7 | Luna Network HSM | Level 3 | Network appliance | 100+ keys | Enterprise, government, finance |
| Thales Luna Cloud HSM | Cloud HSM service | Level 3 | Cloud | Unlimited | Cloud-native enterprise |
| Utimaco CryptoServer | Se-Series | Level 3 | Network appliance / PCIe | 100+ keys | European compliance, GDPR |
| Utimaco u.trust Anchor | Anchor | Level 3 | Network appliance | 100+ keys | IoT, automotive, 5G |
| nCipher (Entrust) | nShield Connect+ | Level 3 | Network appliance | 100+ keys | High-performance signing, PKI |
| Futurex | Vectera Plus | Level 3 | Network appliance | 100+ keys | Financial, banking HSMs |
| AWS CloudHSM | CloudHSM Classic / New | Level 3 | Cloud | Unlimited | AWS-native, HSM-backed KMS |
| Azure Dedicated HSM | Thales Luna 7 (managed) | Level 3 | Cloud | 100+ keys | Azure-native, high compliance |
| Google Cloud HSM | Cloud HSM (Thales Luna) | Level 3 | Cloud | Unlimited | GCP-native, FIPS 140-3 |
| IBM Crypto Express | CE7S | Level 4 | Mainframe | 100+ keys | z/OS, mainframe encryption |
| Marvell | LiquidSecurity | Level 3 | PCIe / Network | 100+ keys | Cloud providers, hyperscale |
AWS CloudHSM Setup:
## Create CloudHSM cluster
aws cloudhsm create-cluster --backup-retention-days 90 \
--hsm-type hsm1.medium --subnet-ids subnet-12345 subnet-67890
## Initialize the first HSM
aws cloudhsm create-hsm --cluster-id cluster-12345678 \
--availability-zone us-east-1a --ip-address 10.0.0.10
## Initialize with crypto officer (CO) and crypto user (CU) credentials
## This requires the CloudHSM client software installed locally
/opt/cloudhsm/bin/cloudhsm_mgmt_util /opt/cloudhsm/etc/cloudhsm_mgmt_util.cfg
## Create a crypto user (for application key usage)
aws-cloudhsm > createUser CU app_user <password>
## Generate a key in the HSM (never leaves the HSM)
/opt/cloudhsm/bin/key_mgmt_util
Command: genSymKey -t 31 -s 32 -l aes256-data-encryption-key
## Verify key is in HSM (no export possible)
Command: getKeyInfo -handle 7
Key Management Systems (KMS)
KMS provides centralized key management with APIs for encryption, decryption, and key lifecycle operations.
| KMS | Cloud | Key Types | HSM Backend | BYOK | HYOK | Auto-Rotation | Price Model |
|---|---|---|---|---|---|---|---|
| HashiCorp Vault | Any | Transit secrets (AES, RSA, EC), PKI | Self-configured (HSM optional) | ✅ Yes | ✅ Yes | ✅ Configurable | Enterprise license + HSM |
| IBM Key Protect | IBM Cloud | Symmetric, Asymmetric | HSM (Level 3) | ✅ Yes | ❌ No | ✅ Configurable | Per key + API calls |
| Oracle Vault | OCI | Symmetric, Asymmetric | HSM (Level 3) | ✅ Yes | ❌ No | ✅ Configurable | Per key + API calls |
AWS KMS Envelope Encryption:
import boto3
from botocore.exceptions import ClientError
kms = boto3.client('kms')
## Generate a data key (DEK) encrypted by KMS key (KEK)
def generate_data_key(key_id):
response = kms.generate_data_key(
KeyId=key_id,
KeySpec='AES_256'
)
# Plaintext DEK — use for encryption, then discard from memory
plaintext_dek = response['Plaintext']
# Encrypted DEK — store alongside ciphertext
encrypted_dek = response['CiphertextBlob']
return plaintext_dek, encrypted_dek
## Encrypt data using DEK (local encryption — fast)
from cryptography.fernet import Fernet
import base64
def encrypt_data(data, plaintext_dek):
# Use DEK for AES-256 encryption
f = Fernet(base64.urlsafe_b64encode(plaintext_dek[:32]))
ciphertext = f.encrypt(data.encode())
# Clear DEK from memory immediately
import ctypes; ctypes.memset(id(plaintext_dek), 0, len(plaintext_dek))
return ciphertext
## Decrypt data
def decrypt_data(ciphertext, encrypted_dek, kms_key_id):
# Decrypt DEK using KMS (KEK)
response = kms.decrypt(CiphertextBlob=encrypted_dek, KeyId=kms_key_id)
plaintext_dek = response['Plaintext']
# Use DEK for decryption
f = Fernet(base64.urlsafe_b64encode(plaintext_dek[:32]))
data = f.decrypt(ciphertext).decode()
# Clear DEK from memory
import ctypes; ctypes.memset(id(plaintext_dek), 0, len(plaintext_dek))
return data
Key Rotation
| Key Type | Rotation Frequency | Rotation Method | Evidence Required |
|---|---|---|---|
| Symmetric data encryption key (DEK) | Per NIST SP 800-57 cryptoperiod and risk (often 1-2 years; new DEK per object with envelope encryption) | New key for new data; re-encrypt when compromised or on schedule | Rotation log, key version history |
| Symmetric key encryption key (KEK) | Every 1 year | Re-encrypt DEKs with new KEK | KMS rotation log, key version history |
| RSA signing key | Every 1 year | New key pair, certificate reissue | Certificate history, signing log |
| TLS certificate key | At each renewal (max 200 days from Mar 2026, 100 from Mar 2027, 47 from Mar 2029) | Automated ACME renewal with a new key | Certificate transparency log, renewal log |
| SSH host key | Every 2 years | New key generation, client update | Host key fingerprint log |
| API signing key | By risk; at least annually | New key, client notification | API key rotation log |
| Database TDE key | By risk; typically annually (protector key) | ALTER DATABASE ENCRYPTION KEY | SQL Server / DB audit log |
| Backup encryption key | Every 1 year | New key, re-encrypt old backups | Backup key rotation log |
| Root CA key | Every 5-10 years | Major ceremony, cross-certification | CA ceremony video, witness signatures |
| Intermediate CA key | Every 3-5 years | New intermediate, certificate reissue | CA operation log |
Key Archival and Destruction
Key Archival:
- Archive keys before destruction for legal/regulatory hold periods
- Encrypt archived keys with a separate archival key
- Store archived keys in offline, physically secure location
- Maintain archival index with key metadata (creation date, purpose, destruction date)
- Retention period set per your retention schedule and the law that applies (for example 8 years for books of account under Companies Act s.128(5))
Key Destruction (NIST SP 800-88 Rev 1):
| Method | Description | Use Case |
|---|---|---|
| Clear | Overwrite with zeros or random pattern | Software keys, memory |
| Purge | Cryptographic erasure (encrypt with new key, destroy new key) | SSDs, encrypted storage |
| Destroy | Physical destruction (shred, pulverize, incinerate) | HSMs, smart cards, hardware tokens |
Key Destruction Checklist:
- Verify no data is encrypted with the key (or re-encrypt first)
- Verify no signatures depend on the key (or re-sign first)
- Remove key from all active systems (HSM, KMS, applications, config files)
- Remove key from all backups (or re-encrypt backups)
- Remove key from all caches and memory
- Destroy key material using NIST 800-88 method appropriate for medium
- Record destruction in tamper-evident log with witness signatures
- Notify all stakeholders of key destruction
- Update CMDB and cryptographic inventory
Dual Control and Split Knowledge
| Principle | Definition | Implementation | Example |
|---|---|---|---|
| Dual control | Two authorized personnel required for critical operation | Two smart cards / two passwords | HSM key generation requires CO + CU |
| Split knowledge | No single person knows the complete key | Shamir's Secret Sharing (SSS) | 3-of-5 key shares required to reconstruct |
| M of N control | M out of N shares required | Threshold cryptography | 2-of-3 administrators to sign certificate |
Shamir's Secret Sharing (Conceptual):
## Using a library like secretsharing or implementing SSS
from secretsharing import SecretSharer
## Split a 256-bit key into 5 shares, requiring 3 to reconstruct
shares = SecretSharer.split_secret('a' * 64, threshold=3, shares=5)
## shares = ['1-...', '2-...', '3-...', '4-...', '5-...']
## Store each share in a separate physical location / HSM / vault
## Reconstruct with any 3 shares
reconstructed = SecretSharer.recover_secret(shares[:3])
📊 Practitioner insight: The worst key management failure we saw in 2025: a fintech stored their AWS KMS customer master key in a plaintext file on an unencrypted S3 bucket, publicly accessible. The key was labeled
production-master-key.pem. Key storage is more important than algorithm choice. A weak algorithm with strong key management is better than a strong algorithm with weak key management. Always use HSM or KMS. Never store keys with data.
Certificate Management
Certificate management is the operational backbone of encryption in transit. Expired certificates cause outages. Self-signed certificates cause audit failures. Rogue certificates enable MITM attacks.
PKI Architecture
| Architecture | Components | Best For | Complexity |
|---|---|---|---|
| Public CA only | Purchase certificates from DigiCert, Sectigo, Let's Encrypt | Small-medium orgs, web services | Low |
| Public CA + Internal CA | Public CA for external, internal CA for internal services | Enterprises with many internal services | Medium |
| Two-tier PKI | Root CA (offline) + Intermediate CA (online) + Issuing CA | Large enterprises, high compliance | High |
| Three-tier PKI | Root CA (offline) + Policy CA + Issuing CA + RA | Government, finance, military | Very High |
| Cloud PKI | AWS PCA, GCP CAS, Azure AD Certificate Services | Cloud-native, scalable | Medium |
Two-Tier PKI Architecture:
┌─────────────────────────────────────────────────────────────┐
│ ROOT CA (Offline) │
│ • HSM-protected, air-gapped, physical security │
│ • Signs intermediate CA certificates only │
│ • Activated only for intermediate renewal (every 5-10 years)│
└──────────────────────────┬────────────────────────────────────┘
│ Signs intermediate cert
▼
┌─────────────────────────────────────────────────────────────┐
│ INTERMEDIATE CA (Online) │
│ • HSM-protected, online, automated issuance │
│ • Issues end-entity certificates (TLS, code signing, email)│
│ • CRL and OCSP distribution │
│ • Renewed every 3-5 years │
└──────────────────────────┬────────────────────────────────────┘
│ Signs end-entity certs
▼
┌─────────────────────────────────────────────────────────────┐
│ END-ENTITY CERTIFICATES │
│ • TLS certificates (200-day max from Mar 2026) │
│ • Code signing certificates (1-3 years) │
│ • Email/S/MIME certificates (1-3 years) │
│ • Client certificates (1-3 years) │
└─────────────────────────────────────────────────────────────┘
Certificate Lifecycle Management
| Phase | Actions | Tools | Timeline |
|---|---|---|---|
| Request | Generate CSR, validate identity, submit to CA | OpenSSL, cert-manager, ACME client | Minutes to days |
| Issuance | CA validates, signs certificate, delivers | CA portal, ACME, API | Minutes to hours |
| Deployment | Install certificate on server, restart service | Ansible, Chef, Terraform, cert-manager | Minutes |
| Monitoring | Track expiry, revocation, transparency | Nagios, Datadog, Prometheus, CertAlert | Continuous |
| Renewal | Generate new CSR, request new certificate, deploy | cert-manager, ACME, custom scripts | ≤ 30 days before expiry |
| Revocation | Publish CRL, OCSP update, notify stakeholders | CA portal, API | Within 24 hours of compromise |
| Archival | Store expired certificate, chain, and private key | Secure vault, HSM | 7+ years |
| Destruction | Securely destroy private key after archival period | HSM purge, NIST 800-88 | Per retention policy |
Let's Encrypt and ACME
Let's Encrypt is a free, automated, open CA. It issues 90-day certificates via the ACME protocol. ACME is the standard for automated certificate management.
cert-manager (Kubernetes) + Let's Encrypt:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: security@singahi.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: singahi-tls
namespace: production
spec:
secretName: singahi-tls-secret
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- singahi.com
- www.singahi.com
- api.singahi.com
ACME Client (certbot), Standalone Server:
## Install certbot
sudo apt install certbot
## Obtain certificate
sudo certbot certonly --standalone -d singahi.com -d www.singahi.com
## Auto-renewal (cron or systemd timer)
sudo certbot renew --dry-run
## Post-renewal hook (restart services)
echo '#!/bin/bash
systemctl reload nginx
systemctl reload postfix' | sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-services.sh
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-services.sh
Certificate Transparency (CT)
Certificate Transparency logs all issued certificates in public, append-only logs. This prevents rogue CAs from issuing certificates for your domain without detection.
| CT Tool | Function | How to Use |
|---|---|---|
| crt.sh | Search CT logs by domain | https://crt.sh/?q=singahi.com |
| Google Certificate Transparency Report | Monitor certificates for your domain | Google Search Console |
| Facebook Certificate Transparency Monitoring | Free CT monitoring | https://developers.facebook.com/tools/ct/ |
| Cert Spotter | CT monitoring with alerts | SSLMate API |
| Censys | Certificate and host discovery | https://search.censys.io/certificates |
CT Monitoring Alert Setup:
## Using Cert Spotter (SSLMate) to monitor for unauthorized certificates
curl -s "https://api.certspotter.com/v1/issuances?domain=singahi.com&include_subdomains=true&expand=dns_names&expand=issuer&expand=cert" | \
jq '.[] | {id: .id, dns_names: .dns_names, issuer: .issuer.name, not_before: .not_before}'
## Set up automated alerts with a cron job:
## 1. Query Cert Spotter daily
## 2. Compare against approved certificate list
## 3. Alert if unauthorized certificate found
CA Selection Criteria
| Factor | Public CA (DigiCert) | Public CA (Let's Encrypt) | Internal CA |
|---|---|---|---|
| Validation | EV, OV, DV | DV only | Organization-controlled |
| Automation | API available | Fully automated (ACME) | Manual or custom automation |
| Trust | Universal browser trust | Universal browser trust | Must distribute trust anchor |
| Certificate lifetime | Up to 200 days (from 15 Mar 2026; falling to 47 by 2029) | 90 days (shorter options available) | Configurable |
| Support | 24/7 enterprise support | Community support | Internal support |
| Compliance | WebTrust, ETSI, FIPS | WebTrust, ETSI | Internal audit only |
| Best for | EV certificates, code signing, email | Web servers, APIs, microservices | Internal services, IoT, device certificates |
Certificate Monitoring and Expiry Alerts
| Tool | Monitoring Type | Alert Channels | Pricing model |
|---|---|---|---|
| Nagios / Icinga | Active check (OpenSSL, curl) | Email, SMS, Slack | Free (self-hosted) |
| Prometheus + blackbox_exporter | Active check, metrics | Alertmanager → PagerDuty | Free (self-hosted) |
| UptimeRobot | Simple HTTPS check | Email, SMS, webhook | Free tier available |
| SSL Labs API | Deep SSL/TLS analysis | API only | Free (limited) |
| cert-manager | Kubernetes-native | Prometheus metrics, events | Free |
| CertAlert | Dedicated certificate monitoring | Email, Slack, webhook | Free tier |
Prometheus blackbox_exporter Certificate Expiry Alert:
## prometheus.yml
scrape_configs:
- job_name: 'ssl_cert_check'
metrics_path: /probe
params:
module: [tcp_connect]
target: ['singahi.com:443']
static_configs:
- targets:
- /
- https://api.singahi.com
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- target_label: __address__
replacement: blackbox_exporter:9115
## Alert rule
- alert: SSLCertificateExpiringSoon
expr: (
probe_ssl_earliest_cert_expiry - time()
) / 86400 < 30
for: 1h
labels:
severity: warning
annotations:
💡 Practitioner tip: The most common certificate failure we see is not expiry, it's intermediate certificate chain misconfiguration. A server sends only the leaf certificate without the intermediate, causing "certificate not trusted" errors on some clients but not others. Always test with
openssl s_client -connect your-site:443 -showcertsand verify the full chain.
Database Encryption
Database encryption protects data where it is most concentrated. A breached database without encryption is a catastrophic data breach. With encryption, it's a security incident.
Transparent Data Encryption (TDE) by Database
TDE encrypts data at the storage layer. It is transparent to applications, no code changes required.
MySQL 8.0 TDE:
-- Step 1: Install keyring plugin (file-based for testing, KMS for production)
INSTALL PLUGIN keyring_file SONAME 'keyring_file.so';
-- For production, use AWS KMS keyring:
-- INSTALL PLUGIN keyring_aws SONAME 'keyring_aws.so';
-- Step 2: Configure keyring in my.cnf
-- [mysqld]
-- early-plugin-load=keyring_file.so
-- keyring_file_data=/var/lib/mysql-keyring/keyring
-- Step 3: Create tablespace encryption
ALTER TABLESPACE innodb_system ENCRYPTION='Y';
-- Step 4: Encrypt specific tables
ALTER TABLE customers ENCRYPTION='Y';
ALTER TABLE payments ENCRYPTION='Y';
-- Step 5: Verify encryption
SELECT TABLE_NAME, TABLE_SCHEMA, ENCRYPTION FROM INFORMATION_SCHEMA.INNODB_TABLESPACES
WHERE ENCRYPTION='Y';
PostgreSQL (CloudNativePG TDE):
## Cluster spec with TDE
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: production-db
spec:
instances: 3
storage:
size: 100Gi
walStorage:
size: 50Gi
# TDE configuration
postgresql:
parameters:
ssl: 'on'
ssl_cert_file: '/etc/ssl/certs/server.crt'
ssl_key_file: '/etc/ssl/private/server.key'
# Encryption at rest via storage class encryption
# (e.g., AWS EBS encryption with KMS key)
Oracle TDE:
-- Step 1: Create wallet
ALTER SYSTEM SET TDE_KEYSTORE=KEYSTORE IDENTIFIED BY wallet_password;
-- Step 2: Open wallet
ALTER SYSTEM SET TDE_KEYSTORE=OPEN IDENTIFIED BY wallet_password;
-- Step 3: Create master encryption key
ALTER SYSTEM SET TDE_KEYSTORE=CREATE KEY IDENTIFIED BY wallet_password
WITH BACKUP USING 'backup_identifier';
-- Step 4: Create tablespace with encryption
CREATE TABLESPACE encrypted_ts
DATAFILE '/u01/app/oracle/oradata/encrypted_ts01.dbf' SIZE 100M
ENCRYPTION USING 'AES256'
DEFAULT STORAGE(ENCRYPT);
-- Step 5: Move table to encrypted tablespace
ALTER TABLE customers MOVE TABLESPACE encrypted_ts;
MongoDB Encryption at Rest:
// Enable encryption at rest during mongod startup
// mongod.conf:
// security:
// enableEncryption: true
// encryptionKeyFile: /etc/mongodb-keyfile
// encryptionCipherMode: AES256-GCM
// Verify encryption status
db.adminCommand({ getParameter: 1, enableEncryption: 1 })
// { "enableEncryption" : true, "ok" : 1 }
// Enable encryption for specific collections (Enterprise)
db.createCollection("encrypted_coll", {
encryptedFields: {
fields: [
{ path: "ssn", bsonType: "string", queries: { queryType: "equality" } },
{ path: "dob", bsonType: "date" }
]
}
})
Column-Level Encryption
Column-level encryption encrypts specific sensitive columns. It requires application changes but provides granular protection.
SQL Server Always Encrypted:
-- Step 1: Create column master key (CMK) in Azure Key Vault
CREATE COLUMN MASTER KEY CMK_AKV
WITH (
KEY_STORE_PROVIDER_NAME = 'AZURE_KEY_VAULT',
KEY_PATH = 'https://singahi-vault.vault.azure.net/keys/CMK1/abc123'
);
-- Step 2: Create column encryption key (CEK) encrypted by CMK
CREATE COLUMN ENCRYPTION KEY CEK1
WITH VALUES (
COLUMN_MASTER_KEY = CMK_AKV,
ALGORITHM = 'RSA_OAEP',
ENCRYPTED_VALUE = 0x016E000001...
);
-- Step 3: Create table with encrypted columns
CREATE TABLE Customers (
CustomerID int,
FirstName nvarchar(50),
LastName nvarchar(50),
SSN nvarchar(11) ENCRYPTED WITH (
COLUMN_ENCRYPTION_KEY = CEK1,
ENCRYPTION_TYPE = DETERMINISTIC,
ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256'
),
CreditCard nvarchar(19) ENCRYPTED WITH (
COLUMN_ENCRYPTION_KEY = CEK1,
ENCRYPTION_TYPE = RANDOMIZED,
ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256'
)
);
MySQL Column-Level Encryption (Application Layer):
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os
## Generate or retrieve key from KMS
key = os.urandom(32) # In production: retrieve from AWS KMS / HashiCorp Vault
aesgcm = AESGCM(key)
## Encrypt column value
def encrypt_column(plaintext: str) -> bytes:
nonce = os.urandom(12)
ciphertext = aesgcm.encrypt(nonce, plaintext.encode(), None)
return nonce + ciphertext # Store nonce + ciphertext together
## Decrypt column value
def decrypt_column(encrypted: bytes) -> str:
nonce = encrypted[:12]
ciphertext = encrypted[12:]
return aesgcm.decrypt(nonce, ciphertext, None).decode()
## Usage: store encrypted data in database
encrypted_ssn = encrypt_column("123-45-6789")
## INSERT INTO customers (ssn) VALUES (%s)
## Store encrypted_ssn as BLOB
Application-Layer Encryption
Application-layer encryption encrypts data before it reaches the database. The database never sees plaintext.
| Approach | Encryption Point | Key Management | Complexity | Performance |
|---|---|---|---|---|
| Client-side encryption | Application code | Application KMS | High | Medium |
| Database proxy encryption | Proxy (e.g., pgbouncer + encryption) | Proxy KMS | Medium | Medium |
| ORM encryption | Object-Relational Mapper | Application KMS | Medium | Medium |
| Field-level encryption | Application service layer | Service KMS | Medium | Medium |
| TDE | Database engine | Database / OS | Low | Low overhead |
📊 Practitioner insight: Another typical failure: TDE enabled on PostgreSQL but the application cached decrypted data in Redis with no encryption. The database was "encrypted" but the cache was plaintext. Encryption must cover the entire data lifecycle: database, cache, backup, log, and analytics. Map every place data lives and encrypt every one.
Application Encryption
Application encryption gives developers control over what gets encrypted and how. It is the most flexible but most complex approach.
Client-Side Encryption
Client-side encryption encrypts data in the browser or mobile app before sending it to the server. The server never sees plaintext.
Browser Client-Side Encryption (Web Crypto API):
// Generate a wrapping key in the browser (or derive from user password)
async function generateKey() {
return await window.crypto.subtle.generateKey(
{ name: 'AES-GCM', length: 256 },
true, // extractable (for backup/escrow)
['encrypt', 'decrypt']
);
}
// Encrypt file before upload
async function encryptFile(file, key) {
const iv = window.crypto.getRandomValues(new Uint8Array(12));
const fileData = await file.arrayBuffer();
const ciphertext = await window.crypto.subtle.encrypt(
{ name: 'AES-GCM', iv: iv },
key,
fileData
);
// Send iv + ciphertext to server
return { iv: Array.from(iv), ciphertext: Array.from(new Uint8Array(ciphertext)) };
}
// Derive key from user password using PBKDF2 (or Argon2 via WebAssembly)
async function deriveKeyFromPassword(password, salt) {
const keyMaterial = await window.crypto.subtle.importKey(
'raw',
new TextEncoder().encode(password),
'PBKDF2',
false,
['deriveKey']
);
return await window.crypto.subtle.deriveKey(
{ name: 'PBKDF2', salt: salt, iterations: 600000, hash: 'SHA-256' },
keyMaterial,
{ name: 'AES-GCM', length: 256 },
false,
['encrypt', 'decrypt']
);
}
Field-Level Encryption
Field-level encryption encrypts individual fields in a data structure. Useful for APIs and structured data.
from aws_encryption_sdk import EncryptionSDKClient
import aws_encryption_sdk.identities
client = EncryptionSDKClient()
## Encrypt specific fields in a JSON document
def encrypt_sensitive_fields(data, key_arn):
sensitive_fields = ['ssn', 'credit_card', 'dob', 'salary']
encrypted_data = data.copy()
for field in sensitive_fields:
if field in data:
plaintext = str(data[field]).encode()
ciphertext, _ = client.encrypt(
source=plaintext,
key_provider=aws_encryption_sdk.identities.KMSKeyProvider(key_arn)
)
encrypted_data[field] = ciphertext.hex()
return encrypted_data
## Usage
encrypted_record = encrypt_sensitive_fields({
'name': 'John Smith',
'ssn': '123-45-6789',
'credit_card': '4111111111111111'
}, 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012')
Tokenization
Tokenization replaces sensitive data with a non-sensitive token. The token has no mathematical relationship to the original data.
| Token Type | Format | Reversibility | Use Case |
|---|---|---|---|
| Random token | UUID or random string | Vault lookup | PCI DSS PAN replacement |
| Deterministic token | Same input → same token | Vault lookup | Analytics, searching |
| Format-preserving token | Same length and format as original | Vault lookup | Drop-in replacement |
| Vaultless token | Mathematically derived | Reversible with key | Performance-critical systems |
Tokenization Example (PCI DSS PAN):
import uuid
from cryptography.fernet import Fernet
class TokenVault:
def __init__(self, key):
self.cipher = Fernet(key)
self.vault = {} # In production: database or HSM-backed vault
def tokenize(self, pan):
# Generate random token
token = str(uuid.uuid4()).replace('-', '')[:16]
# Encrypt PAN and store in vault
self.vault[token] = self.cipher.encrypt(pan.encode()).decode()
return token
def detokenize(self, token):
encrypted_pan = self.vault.get(token)
if encrypted_pan:
return self.cipher.decrypt(encrypted_pan.encode()).decode()
return None
## Usage
vault = TokenVault(key_from_kms)
token = vault.tokenize("4111111111111111")
## Store token in database; PAN is never in database
Format-Preserving Encryption (FPE)
FPE encrypts data while preserving its format. A 16-digit credit card number encrypts to a 16-digit number.
| Algorithm | Standard | Format Preservation | Use Case |
|---|---|---|---|
| FF1 | NIST SP 800-38G | Any format | Credit cards, SSNs, phone numbers |
| FF3-1 | NIST SP 800-38G | Any format | Credit cards, account numbers |
| AES-CBC + custom encoding | Non-standard | Specific formats | Legacy systems |
FPE Example (FF1 with Python):
from pycryptodome.Cipher import AES
from pycryptodome.Util.Padding import pad
## Note: Real FPE requires NIST SP 800-38G compliant implementation
## Use libraries like `mysto-fpe` or vendor FPE solutions
from mystofpe import FF1
fpe = FF1(key=32_byte_key, tweak=b'singahi_tweak', radix=10)
## Encrypt 16-digit PAN
encrypted_pan = fpe.encrypt("4111111111111111")
## Result: "9823746510293847" (16 digits, different value)
## Decrypt
decrypted_pan = fpe.decrypt(encrypted_pan)
## Result: "4111111111111111"
Searchable Encryption
Searchable encryption allows searching encrypted data without decryption.
| Approach | Search Capability | Security | Use Case |
|---|---|---|---|
| Deterministic encryption | Exact match | Weak (leaks equality) | Low-sensitivity fields |
| Order-preserving encryption | Range queries | Weak (leaks order) | Numeric ranges, dates |
| Property-preserving encryption | Various | Variable | Research, specialized systems |
| Homomorphic encryption | Any computation | Strong | Research, not production-ready |
| Blind indexing | Exact match with index | Medium | Email, document search |
Homomorphic Encryption
Homomorphic encryption allows computation on encrypted data without decryption. It is the holy grail of cryptography but remains computationally expensive.
| Scheme | Supported Operations | Performance | Maturity |
|---|---|---|---|
| Paillier | Addition | Slow | Research / limited production |
| BFV / BGV | Addition, multiplication | Very slow | Research |
| CKKS | Approximate arithmetic | Very slow | Research, ML inference |
| TFHE | Any boolean circuit | Extremely slow | Research |
Practical note: Homomorphic encryption is not yet practical for general-purpose production use. Monitor developments from IBM (HELayers), Microsoft (SEAL), and Duality Technologies.
💡 Practitioner tip: The most common application encryption mistake is encrypting the wrong things. Don't encrypt
user_idorcreated_at, these need indexing and searching. Do encryptssn,credit_card,medical_record_number,salary. Use a data classification matrix to decide what gets encrypted, tokenized, or left plaintext.
Cloud Cryptography
Cloud cryptography introduces new models: provider-managed keys, customer-managed keys, bring your own key, and hold your own key. Understanding these models is essential for ISO 27001:2022 compliance in cloud environments.
Cloud Encryption Models
| Model | Key Ownership | Key Location | Control | Use Case |
|---|---|---|---|---|
| SSE-S3 / SSE-GCS | Provider | Provider | Minimal | Default, low sensitivity |
| SSE-KMS / SSE-CMK | Provider (customer-managed alias) | Provider KMS | Medium | Most production workloads |
| BYOK (Bring Your Own Key) | Customer | Provider KMS (customer key material) | High | Regulatory, high sensitivity |
| HYOK (Hold Your Own Key) | Customer | Customer HSM | Maximum | Finance, government, healthcare |
| Client-side encryption | Customer | Customer | Maximum | Maximum sensitivity, end-to-end |
Cloud KMS Deep Dive
AWS KMS:
| Feature | Capability | Notes |
|---|---|---|
| Symmetric keys | AES-256-GCM | Default key type |
| Asymmetric keys | RSA-4096, ECC NIST P-384, ECC SECG P-256 | Signing and encryption |
| HMAC keys | HMAC-SHA-256 | Message authentication |
| Data keys | 256-bit symmetric | GenerateDataKey API |
| Key policies | IAM + key policy | Dual authorization available |
| Rotation | Automatic every 1 year (symmetric) | On-demand rotation supported |
| Multi-region keys | Replicated across regions | DR, global applications |
| Import key material | BYOK | Import from on-premises HSM |
| Custom key stores | HYOK (AWS CloudHSM) | Dedicated HSM partition |
| Grants | Temporary, scoped permissions | Third-party access |
| Monitoring | CloudTrail + CloudWatch | Full API audit trail |
Azure Key Vault:
| Feature | Capability | Notes |
|---|---|---|
| Keys | RSA-4096, EC P-384, EC P-256, AES-256 | HSM-backed or software |
| Secrets | Passwords, tokens, connection strings | Encrypted at rest |
| Certificates | Auto-renewal, issuance, monitoring | Integration with DigiCert, GlobalSign |
| Managed HSM | FIPS 140-2 Level 3, single-tenant | HYOK equivalent |
| Access policies | RBAC + access policies | Fine-grained permissions |
| Rotation | Manual or scheduled | Azure Automation integration |
| Private link | Network isolation | No public internet exposure |
| Backup | Geo-redundant backup | DR capability |
| Monitoring | Azure Monitor + Log Analytics | Full audit trail |
GCP Cloud KMS:
| Feature | Capability | Notes |
|---|---|---|
| Symmetric keys | AES-256-GCM | Default |
| Asymmetric keys | RSA-4096, EC P-384, EC P-256 | Signing and encryption |
| HMAC keys | HMAC-SHA-256 | Message authentication |
| Key rings | Organizational grouping | Region-specific |
| Rotation | Configurable automatic rotation period (symmetric) | You set the period; no default |
| Import key material | BYOK | Wrapped key import |
| Cloud HSM | FIPS 140-3 Level 3 | Dedicated HSM partition |
| VPC Service Controls | Network isolation | Perimeter security |
| Monitoring | Cloud Audit Logs + Cloud Monitoring | Full API audit trail |
Envelope Encryption
Envelope encryption is the cloud-native pattern for encrypting large data with a data key, while the data key is encrypted by a master key.
┌─────────────────────────────────────────────────────────────┐
│ PLAINTEXT DATA │
│ (Large file, database, backup) │
└──────────────────────────┬────────────────────────────────────┘
│ Encrypt with Data Encryption Key (DEK)
▼
┌─────────────────────────────────────────────────────────────┐
│ CIPHERTEXT DATA │
│ (Encrypted file, stored in S3 / Blob / GCS) │
└─────────────────────────────────────────────────────────────┘
│ Store alongside:
▼
┌─────────────────────────────────────────────────────────────┐
│ ENCRYPTED DATA ENCRYPTION KEY (EDEK) │
│ (DEK encrypted by Key Encryption Key — KEK) │
│ KEK is stored in AWS KMS / Azure Key Vault / GCP KMS │
└─────────────────────────────────────────────────────────────┘
AWS Encryption SDK (Python):
from aws_encryption_sdk import EncryptionSDKClient
from aws_encryption_sdk.identities import KMSKeyProvider
client = EncryptionSDKClient()
## Master key provider (KMS)
key_provider = KMSKeyProvider(
key_id='arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012'
)
## Encrypt a large file using envelope encryption
with open('sensitive_data.bin', 'rb') as plaintext_file, \
open('sensitive_data.encrypted', 'wb') as ciphertext_file:
ciphertext, header = client.encrypt(
source=plaintext_file,
key_provider=key_provider
)
ciphertext_file.write(ciphertext)
## Decrypt
with open('sensitive_data.encrypted', 'rb') as ciphertext_file, \
open('sensitive_data_decrypted.bin', 'wb') as plaintext_file:
plaintext, header = client.decrypt(
source=ciphertext_file,
key_provider=key_provider
)
plaintext_file.write(plaintext)
Confidential Computing
Confidential computing encrypts data in use, while it is being processed in memory. This is the third pillar of encryption (at rest, in transit, in use).
| Platform | Technology | Encryption Point | Attestation | Use Case |
|---|---|---|---|---|
| AWS Nitro Enclaves | Isolated VM partition | Memory isolation | Nitro TPM | Sensitive data processing, key management |
| AWS Nitro System | Hardware root of trust | Hardware-level | Nitro Security Module | All EC2 instances |
| Azure Confidential Computing | Intel TDX, AMD SEV-SNP | Memory encryption | Microsoft Azure Attestation | Secure multi-party compute, healthcare |
| Azure Confidential VMs | AMD SEV-SNP | Full VM memory encryption | Azure Attestation | High-sensitivity workloads |
| GCP Confidential Computing | AMD SEV, Intel TDX | Memory encryption | Google Attestation | Data analytics, ML training |
| IBM Secure Execution | IBM Z / LinuxONE | Memory encryption | Hardware attestation | Financial, government |
| Intel SGX | Intel Software Guard Extensions | Enclave memory encryption | Intel Attestation | Legacy confidential computing |
AWS Nitro Enclaves Example:
## Enclave application (runs in isolated environment)
import json
import boto3
from aws_nitro_enclaves_sdk import KMS
def decrypt_data(encrypted_data, encrypted_key):
# Decrypt data key using KMS from within enclave
kms = KMS()
decrypted_key = kms.decrypt(
CiphertextBlob=encrypted_key,
EncryptionAlgorithm='SYMMETRIC_DEFAULT'
)['Plaintext']
# Use decrypted key to decrypt data
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
aesgcm = AESGCM(decrypted_key)
nonce = encrypted_data[:12]
ciphertext = encrypted_data[12:]
return aesgcm.decrypt(nonce, ciphertext, None)
Pattern: for highly sensitive processing, a confidential-computing enclave (for example AWS Nitro Enclaves) keeps decryption keys inside an attested environment: the application runs normally, the enclave processes the sensitive data, and keys never leave the enclave. The auditor's comment: "This is the strongest data protection architecture we've seen in a cloud-native environment." Explore confidential computing for your workload.
Container & Kubernetes Encryption
Container and Kubernetes environments have unique cryptographic challenges: secrets in etcd, pod-to-pod communication, and service mesh encryption.
Secrets Management in Kubernetes
| Approach | Tool | Encryption at Rest | Encryption in Transit | Rotation | Best For |
|---|---|---|---|---|---|
| Kubernetes Secrets (native) | kubectl | AES-256-GCM (etcd encryption) | Base64 (not encrypted) | Manual | Small clusters, low sensitivity |
| Sealed Secrets | Bitnami Sealed Secrets | AES-256-GCM + RSA | Git-encrypted | Manual | GitOps workflows |
| External Secrets Operator | ESO | External KMS | TLS to KMS | Automatic | Multi-cloud, enterprise |
| HashiCorp Vault | Vault + Agent Injector | Transit encryption | mTLS | Automatic | High-security, dynamic secrets |
| AWS Secrets Manager | CSI driver | AWS KMS | TLS | Automatic | AWS-native |
| Azure Key Vault | CSI driver | Azure Key Vault | TLS | Automatic | Azure-native |
| GCP Secret Manager | CSI driver | GCP KMS | TLS | Automatic | GCP-native |
Sealed Secrets (GitOps):
## Install Sealed Secrets controller
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml
## Encrypt a secret for Git storage
kubectl create secret generic db-credentials \
--from-literal=password=supersecret \
--dry-run=client -o yaml | \
kubeseal --controller-namespace=kube-system --controller-name=sealed-secrets \
--format yaml > sealed-db-credentials.yaml
## Commit sealed-db-credentials.yaml to Git — it's safe to share
## Only the cluster controller can decrypt it
kubectl apply -f sealed-db-credentials.yaml
External Secrets Operator (ESO):
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: aws-secrets-manager
namespace: production
spec:
provider:
aws:
service: SecretsManager
region: us-east-1
auth:
jwt:
serviceAccountRef:
name: external-secrets-sa
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: db-credentials
namespace: production
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secrets-manager
kind: SecretStore
target:
name: db-credentials
creationPolicy: Owner
data:
- secretKey: password
remoteRef:
key: production/db-password
property: password
etcd Encryption
etcd stores all Kubernetes secrets. By default, etcd is not encrypted at rest. This is a critical audit finding.
## /etc/kubernetes/manifests/kube-apiserver.yaml
## Add encryption provider configuration:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
- configmaps
providers:
- aescbc:
keys:
- name: key1
secret: <base64-encoded-32-byte-key>
- identity: {} # Fallback (do not use in production)
Better: Use KMS v2 provider for etcd encryption:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
- configmaps
providers:
- kms:
name: myKMSPlugin
endpoint: unix:///var/run/k8s-kms-plugin/socket.sock
cachesize: 1000
timeout: 3s
- identity: {} # Fallback
Pod-to-Pod Encryption with Service Mesh mTLS
Service mesh provides automatic mTLS between all pods. This is the easiest way to achieve encryption in transit for microservices.
| Service Mesh | mTLS Default | Certificate Management | Control Plane | Performance |
|---|---|---|---|---|
| Istio | Optional (strict mTLS configurable) | Istio CA / cert-manager | istiod | Medium |
| Linkerd | Enabled by default | Linkerd identity | linkerd-control-plane | High (lightweight) |
| Cilium | Enabled with WireGuard | Cilium CA / cert-manager | cilium-operator | Very high (eBPF) |
| Consul Connect | Optional | Consul CA / Vault | consul-server | Medium |
| AWS App Mesh | Optional | AWS Private CA | AWS-managed | Medium |
| Traefik Mesh | Enabled by default | SPIFFE/SPIRE | traefik-mesh | High |
Istio Strict mTLS Configuration:
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: istio-system
spec:
mtls:
mode: STRICT # Require mTLS for all services
---
## Verify mTLS is working
## kubectl exec -it deploy/sleep -n foo -- curl -v http://httpbin:8000/ip
## Look for: "SSL connection using TLSv1.3"
Linkerd mTLS (Automatic):
## Install Linkerd with identity (automatic mTLS)
linkerd install --crds | kubectl apply -f -
linkerd install | kubectl apply -f -
## Verify mTLS
linkerd viz tap deploy/frontend -n production | grep tls
## Shows: tls=true for all connections
## Enforce mTLS with authorization policy
kubectl apply -f - <<EOF
apiVersion: policy.linkerd.io/v1beta1
kind: ServerAuthorization
metadata:
name: backend-allow
namespace: production
spec:
server:
name: backend
requiredAuthenticationRefs:
- name: backend
kind: ServiceAccount
EOF
Cilium with WireGuard (eBPF-based):
## Cilium ConfigMap for WireGuard encryption
apiVersion: v1
kind: ConfigMap
metadata:
name: cilium-config
namespace: kube-system
data:
enable-wireguard: "true"
enable-wireguard-userspace-fallback: "false"
# WireGuard uses ChaCha20-Poly1305 for pod-to-pod encryption
cert-manager for Kubernetes Certificates
cert-manager automates certificate issuance and renewal in Kubernetes.
## ClusterIssuer for Let's Encrypt
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: security@singahi.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
---
## Certificate for ingress
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: singahi-tls
namespace: production
spec:
secretName: singahi-tls-secret
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- singahi.com
- www.singahi.com
- api.singahi.com
- app.singahi.com
💡 Practitioner tip: Kubernetes secrets are base64-encoded, not encrypted. Anyone with etcd access can read all secrets. Enable etcd encryption immediately. This is a guaranteed audit finding if not enabled. We verify etcd encryption in every Kubernetes audit using
etcdctl get /registry/secrets/default/my-secretand confirming the value is encrypted, not plaintext JSON.
Quantum-Resistant Cryptography
Quantum computers will break RSA, ECDSA, and Diffie-Hellman. Organizations must prepare now. NIST has published its first post-quantum standards.
NIST Post-Quantum Cryptography Standards (2024)
| Standard | Algorithm | Type | Security Level | Status |
|---|---|---|---|---|
| FIPS 203 | ML-KEM (CRYSTALS-Kyber) | Key Encapsulation | NIST Level 5 | Finalized |
| FIPS 204 | ML-DSA (CRYSTALS-Dilithium) | Digital Signature | NIST Level 3/5 | Finalized |
| FIPS 205 | SLH-DSA (SPHINCS+) | Digital Signature | NIST Level 1/3/5 | Finalized |
| FIPS 206 | FN-DSA (Falcon) | Digital Signature | NIST Level 5 | Draft |
| Algorithm | Classical Security | Quantum Security | Key Size | Signature Size | Speed |
|---|---|---|---|---|---|
| CRYSTALS-Kyber (ML-KEM) | AES-256 equivalent | AES-256 equivalent | 1,568 bytes (public) | - | Very fast |
| CRYSTALS-Dilithium (ML-DSA) | AES-256 equivalent | AES-256 equivalent | 2,592 bytes (public) | 4,595 bytes | Fast |
| Falcon | AES-256 equivalent | AES-256 equivalent | 1,793 bytes (public) | 1,280 bytes | Medium |
| SPHINCS+ (SLH-DSA) | AES-256 equivalent | AES-256 equivalent | 64 bytes (public) | 49,216 bytes | Slow |
| RSA-4096 | ~AES-128 | Broken (Shor's) | 512 bytes | 512 bytes | Fast |
| ECDSA P-384 | ~AES-192 | Broken (Shor's) | 97 bytes | 97 bytes | Very fast |
Migration Planning
Phase 1: Inventory (Now, 2026)
- Catalog all cryptographic implementations (algorithms, key sizes, libraries)
- Identify all RSA, ECDSA, DH, and ECDH usage
- Map data sensitivity and retention periods
- Identify systems that must remain secure for >10 years
- Assess crypto-agility of existing systems (can algorithms be swapped?)
Phase 2: Crypto-Agility (2026, 2028)
- Implement algorithm negotiation in all protocols
- Design systems to support multiple signature algorithms simultaneously
- Add hybrid (classical + post-quantum) key exchange to TLS (experimental)
- Update cryptographic libraries to support ML-KEM and ML-DSA
- Train developers on post-quantum algorithms and key sizes
Phase 3: Hybrid Deployment (2028, 2030)
- Deploy hybrid certificates (classical + post-quantum signatures)
- Enable ML-KEM in key exchange protocols
- Update HSM firmware to support post-quantum algorithms
- Begin post-quantum code signing for software updates
- Update PKI infrastructure to issue post-quantum certificates
Phase 4: Full Migration (2030, 2035)
- Replace all classical-only key exchange with ML-KEM
- Replace all classical signatures with ML-DSA or Falcon
- Deprecate RSA and ECDSA for new systems
- Maintain classical algorithms only for legacy interoperability
- Complete migration of all long-term sensitive data encryption
Hybrid Approaches
Hybrid cryptography combines classical and post-quantum algorithms. If the post-quantum algorithm has a flaw, the classical algorithm still provides security.
TLS 1.3 Hybrid Key Exchange (Conceptual):
├── Classical: X25519 or ECDH P-384
├── Post-quantum: ML-KEM-768 or ML-KEM-1024
└── Combined: Concatenate shared secrets from both
Result: Secure even if one algorithm is broken
Open Quantum Safe (OQS), Experimental:
## Build OpenSSL with OQS support (experimental, not production)
git clone https://github.com/open-quantum-safe/openssl.git
git clone https://github.com/open-quantum-safe/liboqs.git
cd liboqs && mkdir build && cd build && cmake .. -DBUILD_SHARED_LIBS=ON && make && sudo make install
cd ../../openssl && ./config --with-liboqs && make && sudo make install
## Generate hybrid certificate
apps/openssl req -x509 -new -newkey dilithium3 -extensions v3_ca \
-keyout hybrid-ca.key -out hybrid-ca.crt -nodes -subj "/CN=Hybrid CA" -days 365
Cryptographic Implementation
Cryptographic implementation is where theory meets practice. A correct algorithm with a buggy implementation is still broken.
Approved Libraries
| Library | Language | Algorithms | FIPS 140-2/3 | Best For |
|---|---|---|---|---|
| OpenSSL 3.x | C / Bindings | All major | Yes (validated module) | General purpose, TLS, certificates |
| BoringSSL | C / Go | TLS-focused | Yes (via FIPS module) | Chromium, Google services, Go apps |
| libsodium | C / Bindings | Modern, opinionated | No (but secure) | Modern applications, mobile |
| AWS Encryption SDK | Python, Java, C, JavaScript | AWS-optimized | Yes (via AWS KMS) | AWS-native applications |
| Tink (Google) | Java, C++, Go, Python | Modern, misuse-resistant | Yes (via BoringSSL) | Google services, mobile, IoT |
| Botan | C++ | Complete | Yes | C++ applications, embedded |
| wolfSSL | C | Embedded-focused | Yes | IoT, embedded, resource-constrained |
| Mbed TLS | C | Embedded-focused | No | IoT, ARM devices |
| pyca/cryptography | Python | Complete | No (but uses OpenSSL) | Python applications |
| Bouncy Castle | Java / C# | Complete | Yes (Java module) | Java/.NET applications |
libsodium Example (Modern, Secure by Default):
#include <sodium.h>
// Initialize libsodium
if (sodium_init() < 0) {
panic("libsodium initialization failed");
}
// Generate a symmetric key
unsigned char key[crypto_secretbox_KEYBYTES];
randombytes_buf(key, sizeof(key));
// Encrypt a message
unsigned char nonce[crypto_secretbox_NONCEBYTES];
randombytes_buf(nonce, sizeof(nonce));
unsigned char ciphertext[crypto_secretbox_MACBYTES + message_len];
crypto_secretbox_easy(ciphertext, message, message_len, nonce, key);
// Decrypt
unsigned char decrypted[message_len];
if (crypto_secretbox_open_easy(decrypted, ciphertext, sizeof(ciphertext), nonce, key) != 0) {
// Verification failed — message forged or corrupted
}
Common Implementation Mistakes
| Mistake | Why It's Bad | How to Fix |
|---|---|---|
| Hardcoded keys | Keys in source code, Git history, binaries | Use KMS, environment variables (with secrets manager), or HSM |
| Weak randomness | Math.random(), rand(), java.util.Random | Use crypto.getRandomValues(), getrandom(), randombytes_buf() |
| ECB mode | Leaks patterns, no IV | Use GCM, CTR, or CBC with random IV |
| No IV / fixed IV | Same plaintext → same ciphertext | Generate random IV for every encryption, prepend to ciphertext |
| No authentication | CBC without MAC allows tampering | Use AEAD (GCM, ChaCha20-Poly1305) or add HMAC |
| IV reuse with GCM | Complete key recovery with repeated nonce | Use 96-bit random nonce, never reuse with same key |
| Short nonce / counter overflow | After 2^32 blocks, nonce repeats | Use 96-bit nonce for GCM, rotate key before limit |
| Unauthenticated key exchange | MITM can substitute keys | Always authenticate key exchange (signatures, certificates) |
| Timing side-channels | Secret-dependent branching leaks data | Use constant-time comparison, sodium_memcmp() |
| Memory not cleared | Keys remain in memory after use | Use explicit_bzero(), sodium_memzero(), secure heap |
| Padding oracle | Error messages leak padding validity | Use constant-time padding, or better, AEAD |
| Downgrade attacks | Attacker forces weak TLS version | Enforce minimum TLS version, disable fallback |
| Compression side-channels | CRIME, BREACH attacks | Disable compression in TLS, use length-hiding |
| Key reuse for different purposes | Encrypting and signing with same RSA key | Use separate keys for signing and encryption |
Side-Channel Attacks
Side-channel attacks exploit implementation characteristics rather than algorithm weaknesses.
| Attack Type | What It Exploits | Mitigation |
|---|---|---|
| Timing attack | Secret-dependent execution time | Constant-time programming, sodium_memcmp() |
| Power analysis | Power consumption during crypto operations | HSM with power analysis resistance, masking |
| Electromagnetic analysis | EM emissions during computation | Faraday cage, HSM shielding |
| Cache timing | Cache hit/miss patterns | Cache-constant implementations, disable hyperthreading |
| Fault injection | Induced errors to reveal secrets | Fault detection, redundant computation, HSM |
| Acoustic cryptanalysis | Sound from CPU during computation | Sound dampening, distance, HSM |
| Rowhammer | Memory bit flips to bypass isolation | ECC memory, hardware mitigations, memory isolation |
Constant-Time Comparison (C):
#include <sodium.h>
// NEVER use memcmp() for secrets
// Use sodium_memcmp() which is constant-time
if (sodium_memcmp(provided_password, stored_hash, hash_len) == 0) {
// Authentication successful
}
// For clearing memory securely
sodium_memzero(secret_key, sizeof(secret_key));
Constant-Time Comparison (Python):
import hmac
## NEVER use '==' for secret comparison
# Use hmac.compare_digest() which is constant-time
if hmac.compare_digest(provided_signature, expected_signature):
# Verification successful
pass
💡 Practitioner tip: Custom cryptographic implementations frequently contain side-channel weaknesses. Never implement custom cryptography. Use libsodium, OpenSSL 3.x, AWS Encryption SDK, or Tink. These libraries have been audited by experts and include constant-time implementations. If you must implement crypto, hire a cryptographer to review it.
Cryptographic Audit & Validation
Figure · Tiers
Maturity levels for use of cryptography

Cryptographic audit and validation ensures that your implementation meets recognized standards and is free from known vulnerabilities.
FIPS 140-2 / FIPS 140-3
FIPS 140-2 and FIPS 140-3 are NIST standards for cryptographic modules. They define four security levels.
| Level | Requirements | Use Case | Examples |
|---|---|---|---|
| Level 1 | Software-based, basic requirements | General purpose | Software crypto libraries |
| Level 2 | Tamper-evident hardware | Physical security | Smart cards with tamper-evident coating |
| Level 3 | Tamper-resistant, identity-based auth | High security | HSMs, secure enclaves, hardware tokens |
| Level 4 | Tamper-proof, environmental failure protection | Military, government | High-security HSMs, nuclear systems |
FIPS 140-3 Improvements over FIPS 140-2:
| Aspect | FIPS 140-2 | FIPS 140-3 |
|---|---|---|
| Standard basis | Original NIST design | ISO/IEC 19790 aligned |
| Security levels | 4 levels | 4 levels (refined) |
| Software modules | Allowed | More rigorous requirements |
| Firmware security | Limited | Explicit requirements |
| Post-quantum | Not addressed | Framework for future algorithms |
| Validation | CMVP | CMVP (updated program) |
Common Criteria (ISO/IEC 15408)
Common Criteria evaluates IT security products against security targets.
| Evaluation Assurance Level (EAL) | Description | Typical Use |
|---|---|---|
| EAL 1 | Functionally tested | Low sensitivity |
| EAL 2 | Structurally tested | Consumer products |
| EAL 3 | Methodically tested and checked | Commercial, moderate sensitivity |
| EAL 4 | Methodically designed, tested, and reviewed | High commercial, government infrastructure |
| EAL 5 | Semiformally designed and tested | Critical infrastructure, defense |
| EAL 6 | Semiformally verified design and tested | High-risk defense, intelligence |
| EAL 7 | Formally verified design and tested | Military, nuclear, highest assurance |
Cryptographic Module Validation Program (CMVP)
| Step | Action | Timeline | Cost |
|---|---|---|---|
| 1. Pre-validation | Self-testing against FIPS 140-3 requirements | 2-4 weeks | Internal labor |
| 3. Testing | Lab tests all algorithms, key management, physical security | 3-12 months | Lab fees |
| 4. Report submission | Lab submits report to NIST CMVP | 2-4 weeks | Included in lab fees |
| 5. NIST review | NIST reviews report, may request clarification | 2-6 months | Included |
| 6. Certificate issuance | FIPS 140-3 certificate issued | 1-2 weeks | Included |
Penetration Testing Cryptography
| Test Type | Tool | What It Finds | Frequency |
|---|---|---|---|
| TLS/SSL scan | testssl.sh, SSL Labs, nmap | Weak cipher suites, old TLS versions, certificate issues | Monthly |
| Certificate scan | SSLyze, crt.sh | Expired certs, self-signed certs, weak signatures | Weekly |
| Key scan | TruffleHog, GitLeaks, git-secrets | Hardcoded keys, API keys in Git history | Every commit |
| Algorithm scan | grep, semgrep, custom scripts | MD5, SHA-1, DES, RC4, RSA-1024 in code | Every commit |
| HSM/KMS audit | CloudTrail, Azure Monitor, Cloud Audit Logs | Unauthorized key access, unusual operations | Real-time |
| Side-channel testing | FLUSH+RELOAD, cache timing tools | Cache timing vulnerabilities | Annual (specialized) |
| Fuzzing | AFL, libFuzzer, OSS-Fuzz | Implementation bugs, memory corruption | Continuous |
testssl.sh, Complete TLS Scan:
## Install testssl.sh
git clone https://github.com/drwetter/testssl.sh.git
cd testssl.sh
## Full scan of a target
./testssl.sh --full --wide singahi.com
## Check for specific vulnerabilities
./testssl.sh --heartbleed --ccs --ticketbleed --robot --breach --poodle --freak --logjam --drown --sweet32 singahi.com
## Output to JSON for automated processing
./testssl.sh --json --logfile singahi_scan.json singahi.com
Cryptographic Audit Checklist
| Check | Method | Pass Criteria | Evidence |
|---|---|---|---|
| Algorithm compliance | Code review, grep, semgrep | No prohibited algorithms | Scan report |
| Key length compliance | Configuration review | All keys meet minimum sizes | Configuration dump |
| TLS version | testssl.sh, nmap | TLS 1.3 only (external), 1.2 minimum (internal) | Scan report |
| Cipher suite | testssl.sh, SSL Labs | Only approved cipher suites | Scan report |
| Certificate chain | openssl s_client -showcerts | Complete chain, no self-signed, no SHA-1 | Chain dump |
| Certificate expiry | Prometheus, custom check | No certificates expiring < 30 days | Monitoring dashboard |
| Key storage | Infrastructure review | HSM or KMS for all production keys | KMS inventory |
| Key rotation | KMS logs, cron review | All keys rotated per policy | Rotation log |
| Hardcoded keys | TruffleHog, GitLeaks | Zero hardcoded keys in Git history | Scan report |
| Randomness | Code review | CSPRNG used everywhere | Code review report |
| HSM access | CloudTrail, audit logs | Dual control, least privilege, logged | Access log |
| FIPS compliance | FIPS validation certificate | FIPS 140-3 Level 2+ for sensitive data | FIPS certificate |
| Post-quantum readiness | Inventory, architecture review | Inventory complete, migration plan exists | Assessment report |
Metrics & KPIs
Figure · Measures
The measures that show A.8.24 is working
- Encryption coverage100%Monthly
- Encryption coverage100% externalMonthly
- Key rotation compliance100%Monthly
- Certificate expiry> 30 daysDaily
- Certificate transparency coverage100%Continuous
Cryptographic metrics demonstrate control effectiveness to auditors and management.
| Metric | Measurement Method | Target | Frequency | Owner |
|---|---|---|---|---|
| Encryption coverage (at rest) | % of data stores with encryption | 100% | Monthly | Security Engineering |
| Encryption coverage (in transit) | % of services with TLS 1.3 | 100% external, 90% internal | Monthly | Security Engineering |
| Key rotation compliance | % of keys rotated per policy | 100% | Monthly | Key Management Team |
| Certificate expiry | Days until next certificate expires | > 30 days | Daily | Operations |
| Certificate transparency coverage | % of domains monitored in CT | 100% | Continuous | Security Operations |
| Algorithm compliance | % of systems using approved algorithms | 100% | Monthly | Security Engineering |
| HSM/KMS availability | Uptime of HSM/KMS services | 99.99% | Monthly | Infrastructure |
| Key ceremony completion | % of key ceremonies completed per policy | 100% | Per ceremony | Key Management Team |
| Hardcoded key incidents | Number of keys found in code | 0 | Every commit | DevSecOps |
| Crypto audit findings | Number of open findings | 0 critical, < 5 medium | Quarterly | Internal Audit |
| Post-quantum readiness score | % of inventory complete + plan approved | 100% by 2027 | Annual | CISO |
| FIPS compliance coverage | % of sensitive systems using FIPS 140-3 modules | 100% for Highly Confidential | Quarterly | Compliance |
| mTLS coverage | % of microservices with mTLS | 100% for service-to-service | Monthly | Platform Engineering |
| Password hash strength | % of accounts using Argon2id or bcrypt | 100% | Quarterly | Identity Team |
Cryptographic Metrics Dashboard (Conceptual):
┌─────────────────────────────────────────────────────────────┐
│ CRYPTOGRAPHIC HEALTH DASHBOARD │
├─────────────────────────────────────────────────────────────┤
│ Encryption Coverage: ████████████████████ 100% │
│ TLS 1.3 Adoption: █████████████████░░░░ 85% │
│ Key Rotation (90d): ████████████████████ 100% │
│ Cert Expiry > 30d: ████████████████████ 100% │
│ Algorithm Compliance: ████████████████████ 100% │
│ HSM Availability: ████████████████████ 99.99% │
│ Hardcoded Keys: ████████████████████ 0 │
│ PQ Readiness: ██████████████░░░░░░ 60% │
├─────────────────────────────────────────────────────────────┤
│ Alerts: 1 certificate expires in 14 days (api-staging) │
│ Actions: Rotate staging API certificate by 2026-06-25 │
└─────────────────────────────────────────────────────────────┘
Tool Comparison
KMS Comparison
| KMS | Cloud | Key Types | HSM Backend | BYOK | HYOK | Auto-Rotation | Pricing model | Best For |
|---|---|---|---|---|---|---|---|---|
| HashiCorp Vault | Any | Transit, PKI, KV, database | Self-configured | ✅ | ✅ | Configurable | Enterprise license | Hybrid, multi-cloud, dynamic secrets |
| IBM Key Protect | IBM Cloud | Symmetric, asymmetric | HSM (L3) | ✅ | ❌ | Configurable | Per key + API | IBM Cloud native |
| Oracle Vault | OCI | Symmetric, asymmetric | HSM (L3) | ✅ | ❌ | Configurable | Per key + API | Oracle Cloud native |
Certificate Management Comparison
| Tool | ACME | Private CA | CT Monitoring | Auto-Renewal | K8s Native | Best For |
|---|---|---|---|---|---|---|
| cert-manager | ✅ | ✅ | ❌ | ✅ | ✅ Native | Kubernetes, GitOps |
| Let's Encrypt | ✅ Native | ❌ | ✅ | ✅ | ⚠️ | Web servers, APIs, public sites |
Encryption Library Comparison
| Library | Language | Algorithms | FIPS | AEAD | Misuse-Resistant | Best For |
|---|---|---|---|---|---|---|
| OpenSSL 3.x | C | All | ✅ | ✅ | ❌ | General purpose, TLS, legacy |
| BoringSSL | C / Go | Modern, TLS-focused | ✅ | ✅ | ⚠️ | Google services, Chromium, Go |
| libsodium | C | Modern, opinionated | ❌ | ✅ | ✅ | Modern apps, mobile, simplicity |
| AWS Encryption SDK | Python, Java, C, JS | AWS-optimized | ✅ | ✅ | ✅ | AWS-native, envelope encryption |
| Tink | Java, C++, Go, Python | Modern, misuse-resistant | ✅ | ✅ | ✅ | Google services, mobile, IoT |
| Botan | C++ | Complete | ✅ | ✅ | ⚠️ | C++ applications, embedded |
| wolfCrypt | C | Embedded-focused | ✅ | ✅ | ⚠️ | IoT, embedded, resource-constrained |
| pyca/cryptography | Python | Complete | ❌ | ✅ | ⚠️ | Python applications |
| Bouncy Castle | Java / C# | Complete | ✅ | ✅ | ❌ | Java/.NET applications |
| ring | Rust | Modern, TLS-focused | ❌ | ✅ | ✅ | Rust applications, security-focused |
| Monocypher | C | Modern, lightweight | ❌ | ✅ | ✅ | Embedded, constrained devices |
Implementation Roadmap: 12 Weeks
| Week | Phase | Activities | Deliverables | Owner |
|---|---|---|---|---|
| Week 1 | Discovery | Cryptographic inventory: scan all systems, code, configs for algorithms, keys, certificates | Cryptographic inventory spreadsheet | Security Engineer |
| Week 2 | Assessment | Classify findings by risk, map to data classification, identify quick wins | Risk-prioritized remediation list | CISO |
| Week 3 | Policy | Draft cryptographic policy with approved/prohibited lists, key lifecycle, certificate management | Signed cryptographic policy | Compliance Officer |
| Week 4 | Key Management | Deploy HSM or KMS, migrate keys from spreadsheets/config files to vault | HSM/KMS operational, key inventory in vault | Security Engineer |
| Week 5 | Encryption at Rest | Enable FDE on all endpoints, TDE on all databases, SSE on all cloud storage | 100% at-rest encryption coverage | Infrastructure Lead |
| Week 6 | Encryption in Transit | Upgrade all TLS to 1.3, disable TLS 1.0/1.1, configure strong cipher suites | TLS scan report: 100% compliance | Security Engineer |
| Week 7 | Certificate Management | Deploy cert-manager or equivalent, automate renewal, enable CT monitoring | All certificates automated, monitoring active | DevOps Engineer |
| Week 8 | Application Encryption | Implement field-level encryption, tokenization, remove hardcoded keys | Zero hardcoded keys, sensitive fields encrypted | Development Lead |
| Week 9 | Container/Kubernetes | Enable etcd encryption, deploy service mesh with mTLS, Sealed Secrets | K8s cluster encryption verified | Platform Engineer |
| Week 10 | Cloud Cryptography | Implement envelope encryption, BYOK for cloud storage, confidential computing assessment | Cloud encryption model documented, BYOK enabled | Cloud Architect |
| Week 11 | Audit & Validation | FIPS validation check, penetration testing crypto, algorithm scan | Audit-ready evidence package | Security Engineer |
| Week 12 | Quantum Readiness | Complete post-quantum inventory, draft migration plan, present to board | Quantum readiness assessment report | CISO |
Common Audit Failures & Fixes
| Failure | Why It Happens | How to Fix | Time to Fix | Evidence |
|---|---|---|---|---|
| TLS 1.0/1.1 enabled | Legacy application compatibility, forgotten load balancer | Disable at load balancer and server; test legacy apps | 1 day | TLS scan report |
| SHA-1 certificates | Old CA issued SHA-1 chain, intermediate not updated | Reissue certificate with SHA-256 or SHA-384 chain | 1 hour | Certificate reissue log |
| Self-signed certificates in production | Dev/test cert deployed to production, internal CA not trusted | Replace with public CA or properly configure internal CA trust | 2 hours | Certificate replacement log |
| Hardcoded keys in Git | Developer convenience, lack of secrets management | Use TruffleHog to find and rotate; implement KMS/ Vault | 1 week | Git scan report, rotation log |
| Keys in spreadsheets | Manual key management before KMS deployment | Migrate to KMS immediately; audit access to spreadsheet | 1 week | KMS migration log |
| No key rotation | Lack of policy, manual process too burdensome | Enable auto-rotation in KMS; schedule quarterly reviews | 1 day | KMS rotation log |
| Expired certificates | No monitoring, manual renewal forgotten | Deploy cert-manager or monitoring; automate renewal | 1 day | Monitoring dashboard |
| MD5/SHA-1 in code | Legacy hashing, copy-paste from old examples | Replace with SHA-256 or SHA-3; scan with semgrep | 1 week | Code scan report |
| No HSM for root CA | Cost, complexity, lack of awareness | Procure HSM or Cloud HSM; migrate root CA | 2 weeks | HSM certificate |
| No cryptographic policy | Organization focused on other controls | Use our template; customize; get CISO sign-off | 3 days | Signed policy |
| ECB mode in use | Default in old library, developer didn't specify mode | Replace with GCM or CBC + HMAC; update library | 1 week | Code review report |
| No etcd encryption | Kubernetes default, not configured | Enable EncryptionConfiguration with KMS provider | 1 day | K8s config verification |
| Custom cryptography | Developer thought they could improve on AES | Remove custom code; replace with libsodium/OpenSSL | 2 weeks | Code review report |
| No post-quantum assessment | New requirement, not yet prioritized | Complete inventory; draft migration plan; board approval | 2 weeks | Assessment report |
| Certificate chain incomplete | Server config missing intermediate | Update server config with full chain; test with SSL Labs | 1 hour | SSL Labs report |
| Weak SSH config | Default OS configuration, not hardened | Apply SSH hardening config; test with ssh-audit | 1 day | ssh-audit report |
| Passwords hashed with MD5/SHA-1 | Legacy application, old framework default | Migrate to Argon2id or bcrypt; force password reset | 2 weeks | Hash migration log |
| No mTLS for microservices | Assumed network security sufficient | Deploy service mesh (Istio/Linkerd) with strict mTLS | 2 weeks | Service mesh config |
| Backup encryption missing | Backups assumed to inherit storage encryption | Encrypt backups with separate key; test restore | 1 week | Backup encryption config |
| Cloud storage not encrypted | Default SSE-S3 assumed sufficient | Enable SSE-KMS with CMK; verify key rotation | 1 day | S3 bucket policy |
Lessons from Public Cryptographic Breaks
Scenarios 1 to 3 are public research results; scenario 4 is a hypothetical composite.
Scenario 1: Retiring RSA-1024
What happened: RSA-768 was factored publicly in 2009, and estimates showed 1024-bit RSA within reach of well-resourced attackers. NIST disallowed 1024-bit RSA for new signatures after 2013 (SP 800-131A). Organisations that kept RSA-1024 for TLS or VPN key exchange exposed recorded traffic to future decryption.
Impact: Any data encrypted with RSA-1024 and intercepted by an attacker was decryptable. This included old TLS sessions, encrypted emails, and VPN traffic.
Root cause: RSA-1024 was deprecated by NIST in 2010 but many organizations never upgraded. It was the "default" in many systems.
Fix: Move to RSA-2048 or larger, or ECDSA P-256 or larger, with forward-secret key exchange (ECDHE). Re-issue certificates and re-encrypt archived data whose keys were exposed.
Audit lesson: if you select A.8.24, your rules must name current algorithms and key sizes. An auditor finding RSA-1024 in 2026 will treat it as a serious nonconformity.
Scenario 2: The 3DES Sweet32 Attack (2016)
What happened: The Sweet32 attack exploited the small 64-bit block size of 3DES. After 32GB of data encrypted with the same key, an attacker could recover plaintext.
Impact: VPN connections using 3DES were vulnerable to plaintext recovery after sustained traffic. Banking systems using 3DES for transaction encryption were at risk.
Root cause: 3DES was a legacy fallback in many TLS and VPN configurations. It was enabled "just in case" an old client needed it.
Fix: Remove 3DES from all configurations. Use AES-256-GCM or ChaCha20-Poly1305. Monitor for downgrade attacks.
Audit lesson: Legacy algorithm support is a liability. If you support weak algorithms, attackers will force them. A.8.24 requires proactive algorithm deprecation.
Scenario 3: The SHA-1 Collision (2017)
What happened: The SHAttered attack demonstrated practical SHA-1 collisions. Google and CWI Amsterdam generated two different PDFs with the same SHA-1 hash.
Impact: Code signing certificates using SHA-1 could be forged. An attacker could create a malicious file with the same hash as a legitimate file, making it appear signed.
Root cause: SHA-1 was still widely used in certificate chains, Git signatures, and code signing despite known weaknesses.
Fix: Replace all SHA-1 with SHA-256 or SHA-3. Re-sign all code and documents. Update all certificate chains.
Audit lesson: a policy is not enough; auditors look for enforcement. SHA-1 in an issuing certificate chain is very likely to be raised as a nonconformity.
Scenario 4 (hypothetical): Hard-coded Key Exposure at a SaaS Startup
What happened: A SaaS startup had hardcoded AWS API keys in their public GitHub repository. An attacker found the keys, accessed their AWS account, and exfiltrated their entire customer database.
Root cause: Developers used hardcoded keys for local testing and accidentally committed them. No secrets scanning in CI/CD. No KMS in use.
Fix: Implement TruffleHog in CI/CD. Rotate all keys immediately. Deploy HashiCorp Vault or AWS Secrets Manager. Train developers on secure credential management.
Audit lesson: A.8.24 key management requires that keys never be stored in code, config files, or databases. HSM or KMS is mandatory for production keys.
Illustrative Scenario 5: The etcd Plaintext Exposure (2022, Kubernetes Cluster)
What happened: A security researcher gained access to a Kubernetes etcd backup and found all secrets stored in plaintext JSON. The cluster had not enabled etcd encryption.
Impact: All database passwords, API keys, and TLS private keys were exposed. Complete cluster compromise.
Root cause: Kubernetes does not enable etcd encryption by default. The operations team was unaware of the requirement.
Fix: Enable EncryptionConfiguration with KMS provider. Rotate all secrets after enabling encryption. Implement etcd backup encryption.
Audit lesson: A.8.24 applies to all data stores, including Kubernetes etcd. Default configurations are not secure configurations.
Multi-Framework Mapping
Annex A 8.24 Across Major Frameworks
| Framework | Control Reference | Equivalent Requirement | Key Difference |
|---|---|---|---|
| ISO 27001:2022 | A.8.24 | Use of cryptography | Broadest scope: all information, all states |
| SOC 2 (TSC 2017) | CC6.1 | Logical access controls (encryption) | Focus on access, encryption implied |
| SOC 2 (TSC 2017) | CC6.7 | Encryption of data in transmission | Transmission only |
| PCI DSS v4.0.1 | Req 3.4 | PAN storage encryption | Cardholder data specific |
| PCI DSS v4.0.1 | Req 4.1 | Transmission encryption | Cardholder data specific |
| PCI DSS v4.0.1 | Req 3.5 | Key management | Cardholder data specific |
| NIST SP 800-53 Rev 5 | SC-12 | Cryptographic key establishment | Federal systems focus |
| NIST SP 800-53 Rev 5 | SC-13 | Cryptographic protection | Algorithm compliance focus |
| NIST SP 800-53 Rev 5 | SC-17 | Public key infrastructure | PKI focus |
| NIST CSF 2.0 | PR.DS-01 | Data at rest protection | Rest only |
| NIST CSF 2.0 | PR.DS-02 | Data in transit protection | Transit only |
| DORA (EU) | Art. 9 | ICT risk management (encryption) | Financial entities, operational resilience |
| GDPR | Art. 32 | Security of processing (encryption) | Personal data, breach notification exemption |
| HIPAA | 164.312(a)(2)(iv) | Encryption and decryption | ePHI specific |
| FISMA | NIST SP 800-53 | Cryptographic controls | Federal agencies |
| COBIT 2019 | APO13.01 | Managed security (encryption) | Governance focus |
Mapping: ISO 27001 A.8.24 → SOC 2 CC6.7
| ISO 27001 A.8.24 Component | SOC 2 CC6.7 Trust Service Criteria | Evidence Needed |
|---|---|---|
| Cryptographic policy (1) | Encryption policy exists | Signed policy document |
| Key management (2) | Keys are managed securely | KMS inventory, rotation logs, HSM certificate |
| Encryption at rest (4) | Data at rest is encrypted | Storage encryption configuration, scan report |
| Encryption in transit (4) | Data in transit is encrypted | TLS scan report, cipher suite list |
| Certificate management (6) | Certificates are managed | Certificate inventory, renewal logs, CT monitoring |
| Compliance (5) | Encryption meets standards | Algorithm inventory, FIPS certificate |
Mapping: ISO 27001 A.8.24 → PCI DSS v4.0.1
| ISO 27001 A.8.24 Component | PCI DSS v4.0.1 Requirement | Evidence Needed |
|---|---|---|
| Encryption at rest (4) | Req 3.4, PAN encrypted at rest | Database encryption config, TDE status |
| Encryption in transit (4) | Req 4.1, PAN encrypted in transit | TLS configuration, cipher suite list |
| Key management (2) | Req 3.5, Key management procedures | Key lifecycle documentation, HSM/KMS config |
| Key protection (3) | Req 3.6, Key storage | HSM certificate, access logs, dual control evidence |
| Key rotation | Req 3.6.4, Key rotation | Rotation schedule, logs, re-encryption evidence |
| Algorithm compliance | Req 3.5.1, Strong cryptography | Algorithm inventory, no prohibited algorithms |
FAQ
General Questions
Q: Does ISO 27001:2022 A.8.24 require encryption for all data? A: No. It requires that rules for cryptography be defined and implemented based on risk assessment. Not all data needs encryption. Data classified as Public may not need encryption. Data classified as Confidential or Highly Confidential must be encrypted at rest and in transit. A.5.12 (Information classification) determines what gets encrypted.
Q: Is AES-128 sufficient for ISO 27001 compliance? A: AES-128 is not prohibited, but it is not recommended for new systems. Our policy mandates AES-256 for all new implementations. AES-128 may be acceptable for legacy systems with a documented migration plan. Auditors will ask about your rationale if you use AES-128.
Q: Do we need a HSM for ISO 27001? A: Not strictly required by ISO 27001 alone. However, if you handle PCI DSS, financial data, or government data, HSM is mandatory. For general ISO 27001, a KMS (AWS KMS, Azure Key Vault) is sufficient for most organizations. HSM is recommended for root CA keys and signing keys.
Q: Can we use Let's Encrypt for production certificates? A: Yes, for web servers and APIs. Let's Encrypt is a trusted public CA with WebTrust audit. However, it only issues DV certificates. For EV or code signing, you need a commercial CA like DigiCert or Sectigo. For internal services, consider an internal CA or Smallstep.
Q: What is the difference between BYOK and HYOK? A: BYOK (Bring Your Own Key) means you generate key material and import it into the cloud provider's KMS. The provider still holds the key. HYOK (Hold Your Own Key) means you keep the key in your own HSM and the cloud provider never has access. HYOK provides maximum control but requires dedicated HSM infrastructure.
Technical Questions
Q: Should we disable TLS 1.2 entirely? A: For external-facing services, TLS 1.3 only is ideal. For internal services, TLS 1.2 with strong cipher suites may be needed for legacy compatibility. TLS 1.0 and 1.1 must be disabled everywhere. Have a migration plan to move internal services to TLS 1.3.
Q: How do we handle encryption for legacy systems that can't be upgraded? A: Isolate them in a network segment with strict controls. Use a proxy or gateway to terminate TLS 1.3 externally and translate to the legacy protocol internally. Document the risk. Plan for replacement. This is a compensating control, not a permanent solution.
Q: What is the best approach for encrypting data in a microservices architecture? A: Use a service mesh (Istio, Linkerd, Cilium) for automatic mTLS between services. Use envelope encryption with a KMS for application-layer encryption. Store secrets in HashiCorp Vault or cloud-native secret stores. Enable etcd encryption for Kubernetes secrets.
Q: How often should we rotate encryption keys? A: Set cryptoperiods by key type and risk (NIST SP 800-57 Part 1). Typical choices: automatic annual rotation for KMS keys, a new key at every TLS certificate renewal (now at least every 200 days), 1-2 years for signing keys, and 5-10 years for root CA keys. Enable automatic rotation in your KMS where available. The key is not just rotation but also re-encryption of data with the new key.
Q: Can we use the same key for encryption and signing? A: No. Never use the same RSA key for both encryption and signing. This violates cryptographic separation of duties and can lead to attacks. Use separate keys for each purpose. ECDSA keys are only for signing; use ECDH for key exchange.
Q: How do we protect against quantum computers? A: Start with a cryptographic inventory. Identify all RSA, ECDSA, and DH usage. Draft a migration plan to adopt NIST post-quantum standards (ML-KEM, ML-DSA) by 2030. Consider hybrid approaches for critical systems. Monitor NIST and vendor roadmaps.
Audit Questions
Q: What evidence do auditors typically request for A.8.24? A: Signed cryptographic policy, algorithm inventory, key inventory, KMS/HSM configuration, TLS scan reports, certificate inventory, key rotation logs, HSM certificate, FIPS validation certificate (if applicable), code scan results (no hardcoded keys), and training records.
Q: How do we demonstrate key management compliance? A: Show key generation logs, key storage location (HSM/KMS), access control lists, rotation schedules, rotation completion logs, archival procedures, and destruction certificates. Dual control and split knowledge evidence is highly valued.
Q: Is open-source cryptography acceptable? A: Yes, if it is widely used and audited. OpenSSL, libsodium, BoringSSL, and Tink are all acceptable. The key is not whether it's open-source but whether it's validated, maintained, and uses approved algorithms. Avoid obscure or unmaintained libraries.
Q: What happens if we have a non-conformity in A.8.24? A: A minor non-conformity requires a corrective action plan with a timeline. A major non-conformity (e.g., no encryption on sensitive data, no key management) can block certification.
Q: Do we need a dedicated cryptographer on staff? A: Not for most organizations. A security engineer with cryptographic training is sufficient. For fintech, healthtech, or government, a dedicated cryptographer or consultant is recommended.
Indian Regulatory Context and Illustrative Scenario for A.8.24
Indian regulators expect strong encryption and controlled key management, but rarely prescribe algorithms. The RBI Cyber Security Framework in Banks (2016) and the Master Direction on IT Governance, Risk, Controls and Assurance Practices (2023) expect sensitive data to be encrypted in storage and in transit, under a defined key-management process. SEBI's Cybersecurity and Cyber Resilience Framework (2024) and IRDAI's Information and Cyber Security Guidelines (2023) set similar expectations for their regulated entities. The DPDP Act 2023 does not name algorithms; section 8(5) requires reasonable security safeguards, and the DPDP Rules 2025 list encryption, obfuscation, masking and virtual tokens among the measures. Some government tenders ask for certified cryptographic modules (for example FIPS 140-3 or Common Criteria); check the tender.
India cryptography law, in brief:
- IT Act 2000 s.69 and the 2009 Interception, Monitoring and Decryption Rules: on a lawful order, an intermediary or person in charge of a computer resource must assist with decryption. Your key-management procedure should say who handles such requests (this is 27002's "lawful requests for keys" point).
- Digital signatures: legally recognised electronic signatures under IT Act s.3 and s.3A use certificates from CCA-licensed certifying authorities (DSCs, Aadhaar eSign). Web PKI certificates for TLS are a separate system. Statutory filings such as MCA and GST use Class 3 DSCs (GST also accepts Aadhaar-based e-verification). For contracts, decide when a click-to-accept is enough and when you need Aadhaar eSign or a DSC, and keep the signing keys or tokens under your key-management rules.
- Telecom and ISP licences: DoT licence conditions include encryption-related clauses for licensees. Check yours if you hold one.
- Export controls: some cryptographic products and technology are covered by India's SCOMET list and by other countries' export rules, which matters when you ship crypto-enabled products abroad.
Illustrative Scenario (hypothetical), Indian Payment Gateway Key Exposure: A Bengaluru payment gateway discovered hard-coded API keys in a public GitHub repository. The keys granted access to a staging environment that contained production-clone transaction data, including card tokens and UPI handles. Although no fraud occurred, the exposure triggered a PCI DSS investigation, a CERT-In self-report and customer notifications. Root causes included no secrets-scanning in CI/CD, no centralized key management, and developers sharing keys over Slack. Remediation involved deploying HashiCorp Vault, rotating all keys, adding TruffleHog to the CI pipeline, and prohibiting long-lived API keys. The incident became the catalyst for an enterprise-wide cryptographic key management program.
Lessons:
- Never hard-code keys; use a secrets manager or HSM with programmatic rotation.
- Scan every commit for secrets; block merges that contain high-entropy strings.
- Segregate staging and production keys; assume staging data has production sensitivity.
- Maintain a cryptographic inventory and review it quarterly for weak or expiring keys.
📋 Summary Checklist: 48-Hour Quick Start
- Download the Cryptographic Policy Template (Hour 1)
- Customize with your organization name and approved algorithms (Hour 2-4)
- Run
testssl.shon all public domains, document findings (Hour 5-8) - Scan all code repositories with TruffleHog, rotate any found keys (Hour 9-16)
- Inventory all certificates, check expiry, chain, signature algorithm (Hour 17-20)
- Check all databases for TDE, enable if missing (Hour 21-24)
- Sign the policy and publish to the ISMS (Hour 25-28)
- Schedule quarterly cryptographic review (Hour 29-32)
- Enable etcd encryption if running Kubernetes (Hour 33-36)
- Configure KMS auto-rotation for all symmetric keys (Hour 37-40)
- Set up certificate expiry monitoring (Hour 41-44)
- Brief the team on prohibited algorithms (Hour 45-48)
- Done. You have a working ISO 27001-compliant cryptographic program.