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?

  • 15
    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 1 '11 at 15:49
up vote 56 down vote accepted

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.

  • 5
    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 4 '15 at 7: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 4:47
  • Uhh wut @NikitaVolkov? That's exactly what I said, its NOT a better option. – AviD Dec 10 '17 at 7:26
  • My comment addresses "this affords no security benefit, and makes the hash pointless". – Nikita Volkov Dec 10 '17 at 13:13
  • 2
    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. – Adonalsium Aug 3 at 17:10

If your authentication protocol is about sending to the server a password, 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 a SSL tunnel. You are right to want to use a slow hash 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 it 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 making part of the password hashing on the client is not worth the effort.

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.

  • 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
    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
  • 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 1 '11 at 15:48

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.

  • 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 2 '11 at 7: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

Your Answer


By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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