Cryptographic Failures

Cryptographic failures (A02 in the 2021 OWASP Top 10, previously called "Sensitive Data Exposure") cover the ways sensitive data ends up unprotected: sent over plain HTTP, stored unencrypted, hashed with fast or broken algorithms, encrypted with misused primitives, or protected by keys that sit in source code. The consequences are leaked passwords, card numbers, health records, and tokens, plus regulatory penalties under GDPR, PCI DSS, and HIPAA.

The good news: almost all of these failures are avoided by a few principles. Classify your data, encrypt everything in transit, use high-level, well-reviewed libraries instead of assembling primitives, hash passwords with purpose-built algorithms, and manage keys in a KMS. The rule of thumb is simple: don't invent cryptography, and don't hand-wire it either.

TL;DR

Quick Example

Common failures and their fixes:

Core Concepts

Data in Transit

Data at Rest

Algorithms: What to Use and Avoid

Plan for crypto agility: record algorithm and version with ciphertexts and hashes, so you can migrate (for example toward post-quantum key exchange as standards and libraries mature).

Common Misuse

Key Management

Best Practices

Use High-Level Libraries

Prefer APIs that make the right choices for you: libsodium/NaCl (crypto_secretbox, crypto_box), Google Tink, the cryptography package's recipes (Fernet, AEAD classes), and platform frameworks. They handle nonces, authentication, and safe defaults.

Hash Passwords Properly and Upgrade Over Time

Use Argon2id (or bcrypt) with parameters tuned to take tens to hundreds of milliseconds, and rehash on login when parameters change. See password security.

Encrypt Backups and Logs Too

Backups, exports, analytics copies, and logs often contain the same sensitive data with weaker protection. Apply the same encryption and access policies, and scrub secrets from logs.

Automate Detection

Use static analysis (Semgrep, CodeQL) for weak algorithms and hard-coded secrets, secret scanning in repositories, and TLS scanners for endpoints. Include cryptographic review in code review of security-sensitive changes.

Common Mistakes

Hard-Coded Keys and Secrets

Load keys from a KMS or secrets manager at runtime, and rotate any key that was ever committed.

Disabling Certificate Verification

Fix the trust configuration instead: install the internal CA bundle.

Treating Encoding or Hashing as Encryption

Base64 is reversible by anyone. Hashing isn't reversible, which is right for passwords and wrong for data you need back. Choose the primitive that matches the requirement.

FAQ

What's the difference between encryption and hashing?

Encryption is reversible with the right key and protects data you need to read later (messages, card data, files). Hashing is one-way: it produces a fixed digest you can compare against, but not reverse. Use it for integrity checks and, with slow password-hashing algorithms, for storing passwords.

Is SHA-256 okay for passwords?

No. SHA-256 is designed to be fast, so attackers with GPUs can test billions of guesses per second. Password hashing needs deliberately slow, salted, preferably memory-hard algorithms: Argon2id, scrypt, or bcrypt.

Do I need field-level encryption if my database is encrypted at rest?

Storage encryption protects against stolen disks and some infrastructure threats, but anyone with database access (including via SQL injection or leaked credentials) sees plaintext. Field-level encryption adds protection for the most sensitive fields, at the cost of complexity in querying and key management.

How should I generate API tokens and reset codes?

With a cryptographically secure random generator (secrets.token_urlsafe, crypto.randomBytes, SecureRandom), with enough entropy (128+ bits for long-lived tokens). Store only a hash of long-lived tokens, set expiration, and make them single-use where appropriate.

Related Topics

References