4

I found this picture in the Wikipedia nonce article:

enter image description here

To avoid sending the password in clear text and prevent replay attacks, the password is hashed together with one random number from the server (nonce) and one from the client (cnonce). I assume that the server, who knows both random numbers, compute the same hash and compare to verify.

My questions are:

  • Am I right to say that this won't work if the password is not stored in plain text on the server? I fail to see how the server could verify the hash if the password is already hashed (with salt and pepper) on the server.
  • Can this scheme be extended to work with hashed passwords somehow?
  • Does using salt and pepper somehow complicate this even further?
1
  • Similar question and answer here.
    – PwdRsch
    Commented Feb 3, 2016 at 18:35

3 Answers 3

3

Am I right to say that this won't work if the password is not stored in plain text on the server? I fail to see how the server could verify the hash if the password is already hashed (with salt and pepper) on the server.

This scheme does require the password to be stored in clear-text. Very bad.

Can this scheme be extended to work with hashed passwords somehow?

I'm sure it can, but there's no need. The scheme you've referenced is the HTTP digest authentication protocol. It was written in a day when SSL was considered to expensive to implement in many systems. Digest authn provided a way to login over clear-text channels without exposing the password. There's absolutely no reason to do that anymore. SSL is now effectively free.

In general, the risk of storing passwords on the server is considered to outweigh the benefit of having the server not having your password in memory for a short period of time (time from reception of password message until hashing begins and the cleart-text password's memory can be erased).

There are some situations where client-side hashing can make sense. For example, LastPass implements a unique authentication mechanism that involves both client and server hashing. They do this because they use your password as the basis for creating your encryption key and they never want the server to know your encryption key. So what they do is:

  1. Many rounds of PBKDF2 on client to create a strong encryption key.
  2. One round of SHA-256 to turn encryption key into what is effectively your password.
  3. Send password to server. Note that the properties of SHA-256 make it computationally impossible to reverse the password back to your encryption key.
  4. Server performs standard server-side hashing using PBKDF2 and salt.

Basically, the LastPass server does standard password storage but what it gets as a "password" is the result of client-side hashing.

2
  • Note that in this case Lastpass can be fairly sure about the security of the client side hashing since they are serving the code over a previously encrypted channel (HTTPS) or providing it in an extension which is harder to tamper with remotely than a webpage.
    – Matthew
    Commented Feb 3, 2016 at 17:06
  • Thanks for the answer! I know TLS is a good thing and I should use it, but I am interested in this partly as a theoretical exercise, partly as a complement to TLS in situations where the server should never see the password.
    – Anders
    Commented Feb 3, 2016 at 19:11
2

Can this scheme be extended to work with hashed passwords somehow?

Not this scheme. Because of how it works it needs to have the password or some specific equivalent (see https://stackoverflow.com/questions/1000281/storing-password-in-tables-and-digest-authentication for details) to do some necessary computations.

Of course with a naive approach you could modify the scheme so that the hashing of the password would be done on the client already so that a hashed password on the server could be used for comparison. But in this case the hashed original password essentially becomes the new password you need to protect and the original password does not matter at all.

The main idea of a hashed password is that you have an irreversible operation to protect the password in the database and that you will use this irreversible operation on the real password first when adding the hash to the database and later when comparing the entered password against the database entry. This means that you either need to protect the transport (i.e use TLS) or the database (i.e. put the password and clear into the database). If you need a scheme were you can neither protect the database not the transport try public key cryptography.

2
  • "But in this case the hashed original password essentially becomes the new password you need to protect and the original password does not matter at all." Might be wrong here, but if I send hash(password) and hash(password + nounce + cnounce), wont knowing hash(password) be useless since I cant calculate the other hash with a new nounce?
    – Anders
    Commented Feb 3, 2016 at 18:58
  • @Anders: what I mean is if you would keep server_hash(password) in the database then the client could no longer use hash(nonce+cnonce+password) but would need to use hash(nonce+cnonce+server_hash(password)), which essentially makes server_hash(password) the new thing to protect. Commented Feb 3, 2016 at 19:03
1

If you're using a secure channel namely TLS, you don't need to do these sort of tricks.

  • About your first question, yes you're right, this scheme requires the server to have access to password in clear text to be able to reproduce H(nonce+cnonce+password).
  • About your second question, I can't think of a way that won't open you up for replay attacks.(but I'm not the best in this field)
  • No, adding salts doesn't complicate things further than it is while having only the hash on the server side. (If you have the plain password -which you don't, in this scenario- computing the hash with or without the salt isn't much different).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .