HOWTO securely hash passwords


13 Responses to “HOWTO securely hash passwords”

  1. SamLL says:

    Can’t you retrofit it with the following procedure:

    Start with the old password hashes. Create a new table for the new password hashes, one row per user, and initialize it all to empty.

    Whenever a user attempts to sign in, see if they have an entry in the new hash table. If so, check their password against the new hash table, with the new slow hash, and ignore any entry in the old table.

    If they did not have an entry in the new hash table, check their password against the old table with the old fast hash. If it checks out, calculate the slow hash, fill in the row in the new table, and delete their row in the old password has table.

    Unless I’m missing something, this should let you gradually switch hash algorithms with no disruption to any user. Obviously you might still have legacy users who haven’t signed in for a long time still with their old-system hash, but you never store the same password with two different hashes, which might conceivably expose you to some kind of cryptographic attack.

    • ahecht says:

      Even easier is to just create a database of the slow hashes of your old fast hashes. Yes, it means you have to perform two hash operations when a user logs in, but the fast hash is, by definition, fast, and shouldn’t add a lot of overhead. Assuming the slow hash takes 100ms, it would only take LinkedIn 2 days to generate slow hashes for it’s 161 million members if they can get 100 machines working on it.

      • corydodt says:

        Hashes don’t really work like that? Your “inner” hash is the user’s password. Your “outer” hash is, I guess, the inner hash? If I understand you correctly.

        But nobody ever types the “inner” hash. So when it comes time to log in, you don’t have anything to hash again to compare.

        SamLL’s method seems sane, though.

        Edit Ok i think i get it. You keep both hashes, but you still compute the slow hash at login-time. Annoying in that you have an extra column in your database table, but not unreasonable.

      • joshhaglund says:

        yep, nesting hash functions like:  bcrypt(md5( password )) is the easiest and most immediate fix (waiting for users to log in leaves their accounts vulnerable).  But when you make this change you’ll have to take your site down and run:
        update users set md5password = bcrypt(md5password)

        on your db and that could take a quite a while if you’ve got 1million users.

        oh, or, like you said, do this in a different db. maybe flag accounts that updated pw during the 2day update, run them again at the end

    • This is entirely correct. Alternately (and probably easier long-term), add a “version” column to your password table, and overwrite the old password storage value with the new one. Since modern password storage systems like scrypt, bcrypt, PBKDF2, etc are tunable, you’ll want to periodically re-tune your paramaters anyway, so you’ll want the capability to do password versioning anyway.

    • cfuse says:

      Why not just expire people’s passwords and shunt them through the upgraded password procedure?

      If accounts are suspected of being compromised, you lock them and force the user to go through a password change anyway. Aren’t people accepting of this kind of thing by now?

  2. nox says:

    Rainbow tables are ultimately a sophisticated dictionary attack and need some expectation of what the plaintext passwords are in order to be effective.  Wouldn’t have had any luck with my password: oqN1ILN8C8mDyC. (created before linked-in supported symbols in passwords).

    Users need to be educated to take ownership of their security. Lastpass and yubikey is pretty solid.  

  3. mercedes42 says:

    But what does it all MEAN?

  4. LennStar says:

    Even the slowest hash does nothing for security for the top 100 passwords like… password, swordfish and of course 123456

  5. Schneems says:

    Even if you made the wrong decisions from the start, companies can easily secure this data. I did a write up on how a developer could convert insecure passwords to secure passwords in half a day or less

Leave a Reply