Hello software developers,
Please check your code to ensure you're not making one of the following mistakes related to cryptography.
- Writing your own home-grown cryptography primitives (For example: Mifare Classic)
- Exception: For the sake of learning, but don't deploy it in production.
- Using a fast hash function (e.g. MD5, SHA256) for storing passwords. Use bcrypt instead.
- Not using a cryptographically secure random number generator
- Hashing small identifiers and hoping the hash hides the identifier (easily brute-forced)
- Not using authenticated encryption
- Not following an Encrypt then MAC construction
- Using ECB mode (ciphertext blocks will repeat, degrading confidentiality)
- Not using a random IV for CBC mode
- Ever reusing a nonce in CTR mode with the same key
- Using a human-readable password (i.e. "Password123") directly as an encryption key instead of a randomly generated string (or rather a
byte
array if appropriate to your language) - Using the same key for encryption and message authentication
- This isn't really a vulnerability, just a bad practice; use HKDF-SHA256 to split your key into one for encryption and one for authentication.
- Hard-coding an encryption key or password into your client software
- Using RSA with PKCS1v1.5 padding
- Yes, that scheme was broken in 1998. I don't give a damn what your "legacy support" concerns are. Stop using it already.
- Using an unsafe curve for ECC (e.g. many NIST curves)
If you're looking for cryptography right answers, check out the linked gist.
Thank you for your time.
Signed,
A friend who wants your application to be secure
No need to add it to your article. I'll add this here- there is a single edge case exception for ECB mode- using it with a block cipher as a userspace CSPRNG, such as AES. Of course, the only reason you're writing a userspace CSPRNG is because a kernelspace CSPRNG does not exist (embedded, whatever).
The problems with CBC, OFB, CTR, etc. is that the all rely on other a separate IV or nonce object. This is another "thing that can go wrong" and possibly compromise the security of your block cipher CSPRNG. Instead, ECB mode doesn't need anything of these things- just the keyed data.
As a psuedocode example:
This looks a lot like AES-CTR, but doesn't require a nonce to start. The only thing that needs to be provided by the end user, is the key. The security of the userspace CSPRNG rests entirely on the entropy of the key. Further, if the data is only 16-bytes, and never larger, then you'll only be encrypting a single block, and you'll never need to worry about data structure leaks.
Of course, the counter in AES-CTR could be randomly generated by system, but then you have a chicken-and-egg problem. How do you guarantee the entropy of the counter, if you don't have a kernelspace CSPRNG? You could statically set the counter to zero, but then you're no better off than AES-ECB.
Just a thought.