1

I'm designing a user reg/auth system for a website and came up with this design for password based authentication.

I'd like to know if this is reasonable. (ignoring cookies for caching credentials, oauth, etc)

Some things I built into the design, but not sure how much they "help" security:

  1. in case server db is compromised, hashedPw is sent from client so saltedSecret can be reverified. (hashedPw is not stored on server)

  2. challenge (chalSecret) to prevent replay attack

  3. scrypt cost is adjustable over time, but as I expect to use a javascript implementation of scrypt in browsers maybe it's not such a great feature.

Another question is if I can easily secure the initial sending of the saltedSecret during user registration, but I'm assuming using HTTPS is going to be good enough for that.

If there are ways I can simplify this, please do let me know.

NOTE: please see edit section below for changes that simplify this design.

authentication design

EDIT: Some things that occured to me since posting this:

  1. TLS protects against replay attacks, so I can remove the entire challenge section.
  2. on the server side, I should (at minimum) store a hash of the saltedSecret. best is to store an scrypt of it. This has a good side effect of removing the requirement of the user to send the hashedPw during login.
  3. New diagram with these changes: v2 of design
1

The problem I see is that while you're going to a lot of effort to avoid transmitting the users password, saltedSecret has essentially become a password.

The main threat to a transmitted password is that a man-in-the-middle (MITM) will be able to observe it (in the absence of any other forms of encryption) and log into your system.

If we look at how a MITM could exploit your system:

  1. They observe saltedSecret from either a registration or a login (flow 1 or 7)
  2. They make a login request and get told the challengeSalt and chalCost before they've authenticated. (flow 2)
  3. They use the saltedSecret they know to generate chalSecret and login (flow 7)

However you could partially mitigate this by storing saltedSecret and not sending hashedPw or saltedSecret back in flow 7. You'd still be vulnerable from the initial saltedSecret in flow 5.

This is still problematic though because you need a salting and hashing scheme on the server side too if you store saltedSecret. Otherwise if your database is compromised somehow they can use these values to log into your system. But, by hashing the saltedSecret you won't be able to reconstruct chalSecret on the server side and avoid transmitting the generated saltedSecret from the client side.

Generally transport layer encryption such as TLS is considered a sufficient control against MITM attacks, so perhaps you need to weigh up whether implementing client side hashing actually mitigates any significant threats better than just relying on TLS. For example, if TLS is compromised then a MITM could probably inject JavaScript to capture the password any way.

  • Thank you for the feedback @thexacre. Mostly I was focusing on mitigations in case the database gets compromised. Besides MITM (which I hope to be mitigated sufficiently via https), do you have suggestions on how I could simplify this? As you said, it seems like I have a lot of moving parts, but seems like they might all be required.... – JasonS Apr 2 '15 at 1:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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