Assume a website where people log in with their password.

The password is now stored in sql database as:

md5(password + random_salt)

We are adding the possibility for clients to stay logged in and I am trying to find out the best way to do that.

  • Passwords should stay stored in the DB as hashes using some hash function (with the use of a generated salt) - first hash
  • When client logs in with his password, a different hash of his password should be generated (using the previously generated salt) and stored in the relation "second hash".
  • These two hashes should be comparable to each other, so that I could check if the second hash (generated during login) originates from the same string as the first one (generated during registration).

The second hash (the "login" one) would also be used to generate a key to encrypted sensitive user files (probably using AES, or is there a better option?).

I am quite new to this and I'm not sure if I am not being too naive, so I am asking. Is there a way to achieve this? Is there any source where I could read about these "comparable hashes"? I tried searching but I don't really know what to look for.

  • 6
    $\begingroup$ Quick observation: MD5 is not an appropriate password hash. See How to securely hash passwords? for how you should hash passwords. $\endgroup$ Commented Oct 10, 2013 at 10:32
  • $\begingroup$ I would go with random tokens that are simply random values stored in a different database table. $\endgroup$ Commented Oct 10, 2013 at 10:35
  • $\begingroup$ @CodesInChaos Better is random tokens that are issued to the browser, but hashed before being stored in the database. When a user presents the token to the server, hash it and compare to the stored value. This prevents the tokens column from being used to compromise user accounts in the event of a database breach. $\endgroup$ Commented Oct 10, 2013 at 18:24
  • $\begingroup$ Cryptographic hashes are specifically designed to prevent the kind of relationship you are looking for, which would probably be considered a partial collision. I believe your premise of 2 different hashes is inherently flawed. $\endgroup$ Commented Oct 10, 2013 at 18:42
  • $\begingroup$ @CodesInChaos Thanks for the suggestion about md5. I've reviewed my options here and we are probably gonna implement PHP-recommended blowfish hashing. $\endgroup$ Commented Oct 10, 2013 at 23:37

1 Answer 1


Deriving an encryption key and a password hash from a single password

Hash the password, along with a per-account salt.

hash1 = SHA256(password, salt)

hash1 is your encryption passphrase that you pass to GPG.

hash2 = SHA256(hash1)

You keep hash2 in your database to figure out when a user has logged in correctly.

(For additional security, change the first SHA256 out for scrypt, tuned for 50 milliseconds. More trouble than it's worth, IMO.)

Encrypting a file

Use a library like GnuPG. If you don't have GnuPG bindings for your language (I'm guessing you're using PHP), you can hack something together by running gpg from your program with the -c and --passphrase arguments.

Note that if the user changes their password, you need to decrypt and re-encrypt using the new password.

  • $\begingroup$ I wonder why this did not come up to my mind. Thanks, that's it. $\endgroup$ Commented Oct 10, 2013 at 23:26
  • 1
    $\begingroup$ I'd highly recommend using correctly scrypt, bcrypt, PBKDF2, or any other well-known password hash. Such practice is more foolproof than ad-hoc use of SHA256. Proper password hash will correctly combine password and other information like salt. Proper password hash will make breaking low entropy user passwords much slower, if the password DB is ever gotten by a third party. $\endgroup$
    – user4982
    Commented Oct 11, 2013 at 22:00
  • $\begingroup$ @user4982 There's an opportunity cost involved in setting up scrypt. It takes up development time that could be used to lock down unneeded services, to set up AppArmor, to look for SQL injection/XSS/CSRF, or to install fail2ban. All of those things take higher priority in my mind. $\endgroup$
    – Nick ODell
    Commented Oct 11, 2013 at 23:49
  • $\begingroup$ @NickODell I'm aware of some practical concerns in software development. However, usually they should be excluded from the concerns of crypto.SE. They are the field of IT Security. In cryptography, it is just currently recommended practice to just consider normal hash functions (like MD5, SHA256, etc.) incompatible with passwords (or some other low-entropy inputs) and use password-based key derivation functions when such input is used. Generally there exists libraries for that (even for, say, PHP). It is much more likely to get things correctly that way than by rolling your own scheme. $\endgroup$
    – user4982
    Commented Oct 13, 2013 at 9:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.