Search code examples
securitypassword-protection

Increasing security of web-based login


Right now my login system is the following:

  1. Password must be at least 8 characters long, and contain at least one upper and lowercase letter, a number and a symbol.
  2. Password can't contain the username as its substring.
  3. Username, salted+hashed (using SHA2) password stored on db.
  4. The nonce (salt) is unique for each user and stored as plaintext along with the username and password.
  5. The whole login process can only be made over TLS

How would you rank the effectiveness of the following measures to increase security?

  1. Increase password length
  2. Force the user to change the password every X period of time, and the new password can't be any of the last Y previous passwords
  3. Increase nonce size from 32 bytes to 64 bytes (removed for uselessness)
  4. Encrypt the salt using AES, with the key available only to the application doing authentication
  5. Rehash the password multiple times
  6. Use a salt that's a combination of a longer, application-wide salt + unique user salt on the db.

I am not very fond of 1 and 2 because it can inconvenience the user though.
4 and 6 of course are only effective when an attacker has compromised the db (eg: via SQL injection) but not the filesystem where the application is in.


Solution

  • 3 Increase nonce size from 32 bytes to 64 bytes
    4 Encrypt the salt using AES, with the key available only to the application doing authentication
    5 Rehash the password multiple times

    These steps only affect situations where the password file (DB columns) are stolen and visible to the attacker. The nonce only defeats pre-hashing (rainbow tables), but that's still a good thing and should be kept.

    (Again, under the assumption you're trying to minimize the impact of a compromised DB.) Encrypting the nonce means the attacker has an extra brute-force step, but you didn't say where the encryption key for the nonce is stored. It's probably safe to assume that if the DB is compromised the nonce will be plaintext or trivially decrypted. So, the attacker's effort is once again a brute-force against each hash.

    Rehashing just makes a brute-force attack take longer, but possibly not much more so depending on your assumptions about the potential attacker's cracks/second.

    Regardless of your password composition requirements a user can still make a "more guessable" password like "P@ssw0rd" that adheres to the rule. So, brute force is likely to succeed for some population of users in any case. (By which I mean to highlight taking steps to prevent disclosure of the passwords.)

    The password storage scheme sounds pretty good in terms of defense against disclosure. I would make sure other parts of the auth process are also secure (rate limiting login attempts, password expiration, SQL injection countermeasures, hard-to-predict session tokens, etc.) rather than over-engineering this part.