Spot the Problem

In each of the below scenarios, determine what the weakness of the proposed scheme is and how it could be addressed

  1. Passwords
    1. Storing users' passwords hashed with MD5 MD5 is far too weak a hash; an attacker that can access the hash will be able to easily crack them & find the passwords
    2. Storing users' passwords hashed with SHA-512 While SHA is a secure hash, both lacks a salt (meaning that duplicate passwords would hash to the same value, making it easy for an attack to focus their efforts unless you do that yourself) and is too fast (meaning an attacker would be able to try candidate passwords very quickly and hence crack them more quickly)
    3. Storing users' password by encrypting them with AES-CBC You have the same issues with salting as storing with plain SHA, with the additional downsides that passwords of different lengths will encrypt to different lengths, an inside attacker could now steal user passwords, you now need to manage that key and keep it secret
    4. Save work by computing the hash of the password on the client-side & sending that to the server to verify You've essentially just made the hash the password, which is now stored in plain text
  2. Cookies
    1. Storing the users' id in a cookie and encrypting it with AES-CBC The cookie is still vulnerable to tampering; even if the user can't read the cookie, there are practical attacks by which they can modify it so when decrypted, it will become the modified value they desire
    2. Verifying the id in a cookie hasn't been tampered with by sending along SHA512(user_id) The attacker can just run their altered user id through the same hash function! There isn't a secret
    3. Generating a random session token by rolling a fair twenty-sided die The number may be random, but the possibility space is far too small — it's trivial for an attacker to just enumerate all values
    4. Generating a random session token by taking the timestamp of the login in milliseconds The number is far too predicatable, very easy for an attacker to guess plausible values
    5. Generating a random session token by taking the timestamp of the login in milliseconds and running it through SHA512 (i.e. token = sha512(timestamp)) Same problem as previous — even if the token looks more random, if it's just the timestamp going through a simple hash function, it's just as easy for the attacker to guess a timestamp and put it through the same hash function (if there was also a secret, i.e. it was HMAC(timestamp), then that might be better...but then, you could just store HMAC(user_id)).
  3. Secrets
    1. Communicating securely by sending a secret key in the first message, then using that to encrypt all subsequent messages If anyone's snooping, they can also see the secret key and therefore can read all the subsequently-encrypted messages; this is why public-key cryptography is vital!
    2. Storing secrets in an app (that you don't want the user to be able to access) by encrypting them with AES-GCM If the secrets are being decoded in the app, the key must also be present, so a sufficiently motivated user can also get the keys and therefore read the secrets. This is a very hard problem in general; usually the keys are hidden in a separate piece of "tamper-proof" hardware, but it's an arms-race
  4. Synthesis
    1. You need to send some large, secret files. Do you:

      • Zip, then encrypt
      • Encrypt, then zip

      Why?

      Zip, then encrypt; a good encryption algorithm makes the cipher text indistinguishable from random noise, meaning it won't compress at all
    2. You've made the perhaps-foolhardy decision to build your own crypto-system from primitives. You know that you need have a MAC as well as encrypting, but in what order? Do you

      • add the HMAC, then encrypt
      • Encrypt, then HMAC the encrypted content

      Which option should you choose? What would be a potential weakness of the other option?

      Encrypt, then HMAC the entire encrypted message. Otherwise, you have to decrypt before you can verify the message hasn't been tampered with, which leaves you vulnerable to subtle side-channel attacks, e.g. a "padding oracle attack"

Extension

If you want to learn a lot more about cryptography in detail try the Cryptopals crypto challenges