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
@vdzhuvinov there is nothing "elegant" about JOSE and JWT. They had the opportunity to greenfield, but ended up effectively creating JSON-ized SAML full of design mistakes which really shouldn't exist if they had properly studied the attacks on SAML:
alg
is mandatory for tokens but not for keys: this specifically lead to this class of vulnerabilities which shouldn't exist in modern standards: https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/ This is practically backwards:alg
should be mandatory for keys, and tokens should carry only akid
to associate a token with a particular key, and NEVER carry analg
field (insteadkid
is optional andalg
is mandatory for tokens). This way, the verifier always knows the algorithm, and doesn't need to consult the (malleable) part of the token to infer the algorithm. That's just asking for attacks which trick the verifier into using the wrong algorithm (see earlier mentioned link).aud
attribute, but it could've been solved with a cryptographic binding between principals that absolutely ensures claims can't be confused (as seen in e.g. Macaroons). Instead JWT merely carried over SAML's half-solution, and worse, they chose not to make it mandatory, meaning it will not necessarily be automatically checked, so we have two more sharp edges: failure to include anaud
attribute leading to attributes being confused in different contexts, and a potential failure to checkaud
even if it's present. Macaroons, on the other hand, not only cryptographically bind credentials acquired by multiple principals together (i.e. third party caveats / "holder-of-key proofs"), but provide a formal authorization logic for proving them correct.JOSE is an ugly, design-by-committee standard. It is an unopinionated, one-size-fits-all solution. About the best I can say is that JWE and JWS are better than CMS, but that's not saying much.