Security Glossary

Cryptographic Failures

Cryptographic failures occur when sensitive data is not properly protected through encryption, hashing, or key management, leading to data exposure, integrity violations, or authentication bypasses.

Understanding Cryptographic Failures

Cryptographic failures — ranked #2 in the OWASP Top 10 — encompass any misuse or absence of cryptography that leads to data exposure. This includes transmitting sensitive data in plaintext, using weak or deprecated algorithms (MD5, SHA1, DES), hardcoding encryption keys in source code, using encryption without proper initialization vectors, and storing passwords with reversible encryption instead of one-way hashing.

Password storage is the most common area of cryptographic failure. Passwords should never be stored in plaintext or encrypted (encryption is reversible). They must be hashed with a purpose-built algorithm: bcrypt, scrypt, or Argon2id. These algorithms are intentionally slow, making brute force attacks computationally expensive. Generic hash functions like SHA-256, while cryptographically sound for other uses, are too fast for password hashing — GPUs can compute billions of SHA-256 hashes per second.

Encryption failures often stem from rolling your own cryptography instead of using established libraries. Developers who implement their own AES encryption frequently make mistakes with initialization vectors (reusing them, using predictable values), block cipher modes (using ECB which leaks patterns), key derivation (using passwords directly as encryption keys without a KDF), and padding (vulnerable to padding oracle attacks).

The principle is to use high-level cryptography libraries that handle these details correctly: libsodium/NaCl for general encryption, bcrypt/Argon2 for passwords, established TLS libraries for transport encryption. Never implement cryptographic primitives from scratch.

Why This Matters for Vibe-Coded Apps

AI-generated code sometimes implements custom password hashing using MD5 or SHA-256 without salt, creates "encryption" functions that are actually just base64 encoding (which is not encryption), or generates random values using Math.random() instead of a cryptographically secure random number generator. These patterns appear when the AI lacks context about cryptographic requirements.

If your vibe-coded app handles passwords, always use bcrypt (via the bcryptjs package) or your auth provider's built-in password handling. If you need encryption, use a high-level library like libsodium. If you need random tokens or IDs, use crypto.randomUUID() or crypto.randomBytes() instead of Math.random(). When in doubt, use a managed auth provider that handles cryptography for you.

Real-World Examples

Adobe Password Breach (2013)

Adobe stored 153 million passwords encrypted with 3DES in ECB mode without salt. Because ECB encrypts identical plaintexts to identical ciphertexts, attackers could identify common passwords by finding the most frequent encrypted values, then use password hints (stored in plaintext) to decrypt them.

Ashley Madison Bcrypt with MD5 Fallback (2015)

Ashley Madison properly used bcrypt for new passwords but kept an old MD5 implementation that tokenized passwords before hashing. Researchers cracked 11 million passwords through the weaker MD5 path, demonstrating that legacy cryptographic code can undermine modern implementations.

Let's Encrypt Revocation (2020)

A bug in Let's Encrypt's certificate verification code caused 3 million TLS certificates to be issued improperly, requiring mass revocation. The incident demonstrated how cryptographic implementation errors in certificate authorities can have cascading effects across the internet.

Frequently Asked Questions

Why is MD5 considered insecure?

MD5 has known collision vulnerabilities — different inputs can produce the same hash, which undermines integrity verification. For password hashing, MD5 is also far too fast: modern GPUs can compute tens of billions of MD5 hashes per second, making brute force trivial. Additionally, MD5 hashes without salt are vulnerable to rainbow table attacks where precomputed hash databases can instantly reverse common passwords. Use bcrypt or Argon2id for passwords, and SHA-256 or SHA-3 for integrity verification.

What is the difference between encryption and hashing?

Encryption is reversible — you can decrypt ciphertext back to plaintext with the right key. Hashing is one-way — you cannot reverse a hash to recover the original input. Use encryption when you need to retrieve the original data (like stored credit card numbers). Use hashing when you only need to verify data matches (like passwords — you hash the login attempt and compare it to the stored hash). Storing passwords with encryption instead of hashing is a cryptographic failure.

Is base64 encoding a form of encryption?

No. Base64 is an encoding scheme that converts binary data to ASCII text. It provides zero security — anyone can decode base64 without any key or secret. It is commonly confused with encryption because the encoded output is not human-readable. If your application stores sensitive data in base64, that data is effectively in plaintext. Use proper encryption (AES-256-GCM via a library like libsodium) for data that needs to be protected.

How many bcrypt rounds should I use?

The standard recommendation is 10-12 rounds (the "cost factor"). Each additional round doubles the computation time. At 10 rounds, a hash takes roughly 100ms — fast enough for login flows but slow enough to prevent brute force. Increase the cost factor as hardware improves. Test the hash duration on your production hardware: it should take between 100ms and 500ms. If it is faster than 100ms, increase the rounds. Higher values improve security but increase login latency and CPU usage.

Is Your App Protected?

VAS automatically scans for vulnerabilities related to cryptographic failures and provides detailed remediation guidance. Our scanner targets issues common in AI-generated applications.

Scans from $5, results in minutes. Get actionable fixes tailored to your stack.

Get Starter Scan