Ask HN: Is this the right way to create a login?

4 points by xerophtye ↗ HN
Our current model is that we store salted hash passwords where the username is the salt.

When the user opens a login page, the server creates a session and sends a random string along with the login page. On the client side, JS computes the salted hash of entered password (salt = username), then appends the random string as salt and computes hash again. Then sends this hash to us via post.

The server matches received hash against hash of (stored hash+random string that we sent).

So is this method secure? If not, what can we do to improve it?

7 comments

[ 2.0 ms ] story [ 26.0 ms ] thread
If you're storing salted hashes, substantial portions of your username/password pairs will be decrypted as soon as you lose a copy of your DB, unless you are intentionally choosing a hashing algorithm which is slow (bcrypt/scrypt) rather than one which is fast (most of them).

You also seem to be reinventing a few wheels here, and I feel there's a "We don't want to buy an SSL certificate" motivating part of it, which is a poor call. Buy the SSL cert. Send the user's input to the server. Compare it against the bcrypted hash. Simple, easy to implement, hard to screw up, resistant against you losing your DB.

Don't forget to build a hash round counter into whatever bcrypt/scrypt setup you use. Don't just take the salt+password and run it through bcrypt once – do it as many times as your hardware setup permits, and store that counter as part of the hash (~bcrypt~DKM303mGdoadyHerichurkman~5000~de455ae…).

As your computing power grows, you can increase the number of rounds.

If you ever replace your login algorithm like Kickstarter did, give your users a few months to log in to upgrade their stored hashed password. Then purge any outdated hashes. Let those users do password resets.

Don't do this, as this is exactly the point of using bcrypt in the first place. Just adjust the bcrypt cost factor.
Well before we were simply sending the password and comparing with hash on server side, but a pentest team retrieved sent passwords from browser's memory (not entirely sure how), so they recommended that we send hashed passwords.

The random string which is part of session is to avoid replay attacks. But i suppose SSL should be taking care of it, right?

... If you have arbitrary memory access on the browser's machine, your site's password is screwed no matter what you do, and that is very much not the most interesting thing to be done with that access.

Your session management / CSRF token will take care of replay attacks without you having to worry about integrating that into your login page. If your sessions aren't secure against replays they can be replayed after the login anyhow.

Your approach doesn't work for people without js, and is ineffective against man-in-the-middle-attacks. You still need https to secure against people modifying the page so they get the plain password, and if you are going https, the js stuff isn't needed.

Here's all you need to know: http://stackoverflow.com/a/477578

Thanks, that's a ton of help. I tried stackoverflow but apparently i wasn't using the right keywords. Bookmarking this for future reference