Cryptographic Failures
2) Cryptographic Failures
What this means (simple)
A cryptographic failure happens when sensitive data is not protected correctly.
Sensitive data includes:
- Passwords
- Credit card numbers
- Personal data (name, phone, address, ID)
- API keys and tokens
- Session cookies
If protection is weak, attackers can read, steal, or change data.
Very common real-life situations
- Passwords are stored as plain text in the database.
- Passwords are hashed with weak algorithms like MD5 or SHA1.
- Website uses HTTP instead of HTTPS, so data travels in clear text.
- Encryption keys are hardcoded in source code.
- Old TLS settings are enabled (weak ciphers/protocols).
- Sensitive data is logged in application logs.
Step-by-step: how an attack happens
Scenario A: Plain-text passwords
- Attacker finds SQL injection or steals DB backup.
- Attacker opens users table.
- Password column contains real passwords (password123, qwerty).
- Attacker logs into user accounts immediately.
- Attacker tries same passwords on other websites (credential stuffing).
Scenario B: Weak password hashing
- App stores hashes using MD5.
- Attacker steals hash list.
- Attacker runs fast cracking tools with rainbow tables/GPU.
- Many passwords are recovered in minutes/hours.
- Accounts are taken over.
Scenario C: No HTTPS
- User logs in on public Wi-Fi.
- Traffic is sent over HTTP.
- Attacker sniffs network packets.
- Attacker reads username/password or session cookie.
- Attacker hijacks session and acts as user.
Tricky concepts explained clearly
1) Encryption vs Hashing
- Encryption is reversible.
- Hashing is one-way.
Think:
- Encryption = locked box with a key. If you have key, you can open it.
- Hashing = blender. You cannot “unblend” it.
Use:
- Passwords: hashing (never decrypt passwords).
- Data like card numbers: encryption (you may need to read later).
2) Salt
A salt is random data added to each password before hashing.
Why:
- Two users with same password should not have same hash.
- It blocks many precomputed attacks (rainbow tables).
Rule:
- Use unique random salt per password.
- Store salt with hash (this is normal and safe).
3) Pepper
A pepper is a secret extra value (like app-wide secret) added before hashing.
Why:
- If DB is stolen, attacker still misses pepper.
- Adds extra defense.
Rule:
- Keep pepper outside DB, e.g., secret manager.
4) Key management
Encryption is only as strong as key handling.
Bad:
- Key in source code
- Key in Git repo
- Same key forever
Good:
- Store keys in KMS/secret manager
- Rotate keys
- Limit who can access keys
- Log key usage
5) “Data in transit” vs “data at rest”
- In transit = moving over network
- At rest = stored in DB/files/backups
Need both:
- HTTPS/TLS for in transit
- Proper encryption/hashing for at rest
6) Randomness
Crypto needs strong random numbers.
Bad:
- Using predictable random (Math.random) for tokens/IVs
Good:
- Use cryptographically secure random generator from your platform.
How to prevent (implementation steps)
- List all sensitive data your app handles.
- Remove data you do not need to store.
- Enforce HTTPS everywhere.
- Set Secure, HttpOnly, SameSite on cookies.
- Hash passwords with Argon2id (or bcrypt/scrypt if needed).
- Use per-user random salt for password hashes.
- Encrypt sensitive stored data using modern authenticated encryption (like AES-GCM).
- Keep keys in a secrets manager/KMS, not code.
- Disable old protocols/ciphers (SSL, TLS 1.0/1.1).
- Never log passwords, tokens, or full card data.
- Add automated checks for weak crypto use.
- Rotate keys and secrets regularly.
Password storage: correct flow (easy model)
- User sends password at signup.
- Server generates random salt.
- Server computes Argon2id(password + salt + optional pepper).
- Server stores: hash + salt + algorithm parameters.
- On login, server recomputes hash and compares.
- Server never decrypts or shows password because it is not stored in reversible form.
Quick “bad vs good”
- Bad: MD5(password)
Good: Argon2id with strong parameters.
- Bad: HTTP login page
Good: HTTPS-only with HSTS.
- Bad: API key in source code
Good: API key in secret manager.
- Bad: Encrypt data but store key in same DB table
Good: Separate key storage with strict access control.