48

Let's say in my database I store passwords hashed with salt with a fairly expensive hash (scrypt, 1000 rounds of SHA2, whatever).

Upon login, what should I transfer over the network and why? Password or its hash?

Is it possible to protect such login over an unencrypted channel like HTTP?

Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949
Konrad Garus
  • 755
  • 1
  • 7
  • 8
  • 16
    Is this a rhetorical question? (Intended to generate curiosity and discussion?) Or do you have an actual implementation requirement to authenticate over HTTP? It's an interesting question, but the simple answer is "use SSL" and there are VERY few reasons why a good system would deviate from that. – Mark E. Haase Jul 01 '11 at 15:49

4 Answers4

67

If you transfer the hash from the client, this affords no security benefit, and makes the hash pointless:
If a user can login by sending the hash to the server, then the hash is effectively the password.

AviD
  • 72,138
  • 22
  • 136
  • 218
  • 8
    Hashing on the client affords some benefit to the user since the attacker will not compromise their password which if compromised would open up that user to the possibility of having other accounts that they hold compromised if they have used the same password (which you can not prevent). This is not to say that the client is the best place to hash, but in the absence of any other hashing doing so on the client **does** afford some security benefit. – jpierson Dec 04 '15 at 07:44
  • If one was able to eavesdrop to catch the hash, he would catch the original password otherwise. How could that be a better option?! – Nikita Volkov Dec 10 '17 at 04:47
  • Uhh wut @NikitaVolkov? That's exactly what I said, its NOT a better option. – AviD Dec 10 '17 at 07:26
  • My comment addresses "this affords no security benefit, and makes the hash pointless". – Nikita Volkov Dec 10 '17 at 13:13
  • Right, exactly....? Not sure what you mean, I said that there is no security benefit to sending the hash, and from a security PoV would be no better off? – AviD Dec 10 '17 at 14:32
  • 1
    I think that protect the password with hash afford aditional security and it is not same that send the hash instead of password, because in some times the user uses the same password (or little variations adding once character) in other websites/services. In general lines telling about security is not good that the password can be read clearly. – Jeferson Tenorio Aug 03 '18 at 16:50
  • 3
    Could you not cook up something involving a nonce and a shared secret so that only the server and the client can send that particular hash? Wait I just described something like TLS didn't I. – Monica Apologists Get Out Aug 03 '18 at 17:10
  • @JefersonTenorio of course the password shouldn't be read clearly, that's what TLS is for. The point is if you DON'T use TLS, then effectively the hash you send *is* the password - and it makes no difference, since you are still sending *that* in plaintext. (And if you are using TLS, then it is irrelevant anyway). – AviD Aug 05 '18 at 09:07
  • @Adonalsium yeah what you said ;-) – AviD Aug 05 '18 at 09:07
  • Hypothetically, couldn't you have a system like this: 1. server sends "please append SALT to your hashed password" 2. clientside hashes "mypassword" encrypted as "HASH_A", with SALT, so "SALTHASH_A", hashed as "HASH_B" 3. server has "HASH_A" in the database, it gets "HASH_B" from the client, it tries encrypting "SALTHASH_A" and gets "HASH_B", success. Then the server's code would never even have the opportunity to even know a cleartext password (which can be leaked via bugs, logs, mistakes, etc.). Wouldn't that be a benefit even in addition to HTTPS? – jrh Sep 17 '21 at 19:02
26

If your authentication protocol is about sending a password to the server, or a hash of the password, with plain HTTP, then this is inherently very weak, for two reasons:

  • Someone spying on the line could record what the client sends. If just sending these bytes grants access, then the attacker could simply send them again. That's a replay attack. This issue is what @AviD alludes to in his answer. No amount of hashing will fix that. Some protocols try to correct this issue by including a "challenge" from the server (a random value, created anew for each connection), to be hashed together with the password on the client; that's what HTTP Digest authentication is about.

  • Even if the authentication worked, this is still plain HTTP, so whatever data will be sent afterwards will be vulnerable to eavesdropping and alterations by attackers. If the transport medium is unprotected, then the authentication will deter only the most unsophisticated of attackers. This is where HTTP Digest fails.

Therefore, you really need SSL (aka HTTPS), not only to convey the password or hash thereof, but also the remainder of the conversation between client and server.


I hereafter assume that the protocol is run within an SSL tunnel. You are right to want to use a slow hash function like bcrypt or PBKDF2; note that a salt is also needed to prevent cost sharing (e.g. precomputed tables). Slow, salted hashing is used to cope with the intrinsic weakness of passwords. Now, you might want to offload some of the hashing effort on the client. This may work, but it raises some practical issues:

  • Since the password processing must include a salt, a new one for each password instance, then the salt must be conveyed to the client, so that the client may include the salt in the hashing it performs. This increases the protocol complexity: the client must first send the user name to the server, then the server must send back the salt, and (only then) can the client begin to hash the password. This is one more network roundtrip than with the usual "send user name and password as one POST request".

  • Slow hashing is about accepting to spend a lot of CPU on each password, so that the attacker also has to spend a lot of CPU on each password. But if the spent CPU is on the client, then we cannot raise it as much as we would like, because: 1) there are clients which have very little CPU (say some cheap smartphones or tablets), and 2) the Web context implies using JavaScript, and JavaScript performance is really bad when it comes to hashing (say at least 20 times slower than C code).

Therefore usual wisdom is that performing part of the password hashing on the client is not worth the effort.

Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949
4

Both options are insecure.

Transferring the password will make your protocol plain-text. Transferring the hash, will make you vulnerable to replay attacks.

APOP is a login implementation for the POP protocol. This allow the protocol to keep the password private from any listeners on the network. A drawback to this is that both the client and the server need to know the password in plain text, as this is the shared secret. Prior to the that of the protocol both the client and the server have < password > The protocol communication is basically like this:

  1. Client connects to server and send a random token (T1)
  2. Server sends a random token (T2)
  3. Client send M = sha( T1 + T2 + < password: client's copy > ) to the server
  4. The server checks if sha( T1 + T2 + < password: server's copy > ) matches M (the hash just received).

Here, the server knows both the magic and the password, and is able to determine if the user knows the correct password without exposing it to any listeners.

The best practice would be to securely store the hashes in the database, and rely on encrypted channels.

this.josh
  • 8,843
  • 2
  • 29
  • 51
Dog eat cat world
  • 5,759
  • 1
  • 27
  • 46
  • 2
    That's still vulnerable to MitM, if the sniffer intercepts T1, passes it onto server, then the same with T2, it can generate it's own sha(T1+T2+...). – Marcin Jun 30 '11 at 14:02
  • 1
    True, the MitM vulnerability is the possibility to bruteforce the hash to reconstruct the original password once T1 and T2 is known. Replay attacks however is not possible if T1 and T2 is not reused (time incremented etc). – Dog eat cat world Jun 30 '11 at 14:06
  • 3
    http://en.wikipedia.org/wiki/Needham%E2%80%93Schroeder_protocol has a good example for a similar protocol, the attack, and the fix. Good reading. – Marcin Jun 30 '11 at 14:13
  • @Marcin I'm still not convinced this is vulnerable to a MitM attack. Some points are left out in the original answer, but these are easily fixed by choosing non-reusable random tokens. A MitM attack you described in your first comment does not expose the shared secret, since it will never be transmitted. The session might be hijacked after the login procedure is done, but this can also be fixed by signing, or encrypting the rest of the sessions with the shared secret (password). – Dog eat cat world Jun 30 '11 at 14:27
  • Are you using the sha(T1+T2+whatever) as the encryption key for data xfer, or just an authentication? – Marcin Jun 30 '11 at 14:47
  • It is used as authentication, to establish that both parties have the same whatever/"shared secret". The protocol can of course be extended to further use this shared secret to establish an encrypted channel. But that is another discussion that will involve further weaknesses outside of this scope. – Dog eat cat world Jun 30 '11 at 14:48
  • 6
    This is an interesting algorithm, but it is beside the point: you may not be leaking the password, but what is the point of having a password if you're not going to secure the rest of the session? Over http a man in the middle might not get the user's password, but he will see all of the content transferred during the session, and if a session ID is used, then the MITM can hijack the user's session. Unless this is a rhetorical questions, the correct answer has to be: "use SSL". – Mark E. Haase Jul 01 '11 at 15:48
  • When using APOP, is there any reason not to use the exchange with passwords hashed via conventional means, so as to avoid requiring the server to have an unhashed password? Someone who gets a copy of the server's hashed password would be able to impersonate the user on that site, but would not be able to use the password on any other sites. – supercat Jul 21 '14 at 16:49
-2

Neither, Ideally one uses a challenge response mechanism and then transfers that hash, and does all this over a cryptographically secure channel like SSL. But most users don't like it taking 5 minutes just to log in. What's more, the user should check all this before using it.

Ultimately it depends on just how much security one needs, and what attack vectors one is trying to protect from, but using SSL is always a good idea.

ewanm89
  • 2,043
  • 12
  • 15
  • 1
    Using SSL is all that is needed. Using SSL does not make it "take 5 minutes just to log in". The level of pessimism here is not warranted. – D.W. Jul 02 '11 at 07:09
  • I kinda inferred that. What we can do and what is sensible in a particular situation is two different things – ewanm89 Jul 25 '11 at 17:36