27

If you were to hash a user's password prior to sending it across the line and leaving it in plain-text in memory, would this improve the security of the application?

I would assume this mitigates a small fraction of vulnerabilities by protecting the data stored in the clients memory. But really if we're worried about someone reading the client's memory there are probably bigger problems that we can't address.

There's something that doesn't feel right about hashing on the client's end.

Is password hashing on the client end a common practice? Are there any other advantages or disadvantages to doing it?

EDIT: Given the communication channel is secure (SSL). Under what conditions would it be acceptable and worthwhile to use such an approach. I'm asking this because it was suggested by a "security professional" that I use such a scheme during some application functions.

IaCoder
  • 10,849
  • 10
  • 33
  • 45
  • 3
    Accepted answer is wrong. **It does give you an advantage,** provided you salt-hash the hash itself on the server side as well. See http://security.stackexchange.com/a/23285/2379 , http://security.stackexchange.com/a/23033/2379 – Pacerier Dec 02 '14 at 00:31

10 Answers10

20

No.

When the client sends something, whether it is P or H(P) or H(H(P)) anyone who intercepts this can simply resend the exact same thing, thus making any function like this equivalent to using the password directly.

That's why you should use a nonce; The server can give out some random garbage k and the client will calculate H(P,k) and send it to the server. HMAC is a popular implementation of this method.

Provided the server never accepts the same nonce twice, this is secure against a replay attack.

geocar
  • 8,545
  • 1
  • 26
  • 37
  • 12
    ... but this creates a DoS opportunity: capture every server nonce that's sent to the client, and use it before the legitimate client can; voila, now the client can't log in at all, as every nonce is already expired by the time the client sends its request. Not an entirely practical scenario, but as always, security needs to be in balance with usability, and sometimes adding one reduces the other. – Piskvor left the building May 18 '11 at 19:47
  • 5
    As other answers point out, there are some *slight* advantages to hashing on the client since many users re-use passwords with multiple services. – pettys May 22 '14 at 21:21
  • @pettys: No there aren't. There are advantages to doing encryption or an mac-protected hash, but there are no advantages to doing an unsalted and unprotected hash on the client. – geocar Jun 07 '14 at 07:46
  • @Piskvor: Hashing the password on the client doesn't solve that problem, and such a DoS opportunity is unlikely since the attacker can simply modify the user experience in such a situation. – geocar Jun 07 '14 at 07:50
  • 3
    @geocar: I agree with your main point that if you're relying on this for end-to-end security you are Doing It Wrong; I agree with your advice of using a nonce/HMAC to beef it up. I just disagree with your absolute declaration that there is absolutely no benefit to client hashing - in other answers, Lucas Oman, David Thornley and user1700819 all point out potential *slight* benefits of hashing on the client. – pettys Jun 09 '14 at 14:42
  • 1
    ...I might be misunderstanding something here- and feel free to correct me if I am- but doesn't an HMAC require both parties to share the same key, right? That being the case, if the site uses password-based authentication, but doesn't hash client-side, then the database _must_ store the password directly or it can't verify the HMAC. Which would itself constitute a serious vulnerability. A vulnerability which would be ameliorated- at no visible cost to the user or app host by using an HMAC of H(K=password, m=username) instead of the password directly. – Parthian Shot Jun 25 '14 at 20:23
  • 1
    Storing encrypted passwords is idiotic if you don't actually need the passwords themselves (and the associated overhead of worrying about everyone's passwords being leaked all at once if someone cracks your server), which you don't. All you should really need are the authentication tokens. – Parthian Shot Jun 25 '14 at 20:25
  • The nice thing about that is attackers won't be able to crack passwords in parallel (because they're salted with login names), you don't need to provide nonces every time (so you can serve static login pages), you can still implement replay-attack-proof HMAC authentication on top of the first client-side HMAC, you never have to store or see the password, and you know that the security of the password depends upon the entropy of the password itself, as it must (since it's an HMAC, and they're designed to hide the key). – Parthian Shot Jun 25 '14 at 20:33
  • @ParthianShot - HMAC requires both parties perform a computation using the key, but it doesn't require they *store* the key; The state for `H(P,` can be saved safely if it's padded (which you'll notice it is with HMAC). – geocar Jun 28 '14 at 12:46
  • @geocar But assumedly by `H(P,` you mean information derived only from the key, right? If that's the case Eve can collect a bunch of those states for different users of that state and figure out which ones are weak in parallel- not by reversing the one-way function used, but by guessing likely passwords. Same reason you need salts. – Parthian Shot Jun 28 '14 at 20:33
  • With a salt, the client can no longer force the server to prove it knows the key (since it doesn't). – geocar Oct 12 '14 at 16:06
15

Sending a hashed password won't improve security on your site, as others have pointed out (since you accept a hashed password, all the bad guy needs to know is the hashed version). It's also not really secure, since the bad guy can presumably load your login page and examine the Javascript or Java deployed.

What it does do is prevents somebody watching the packets from being able to pull out a password, and that is moderately useful. Many people use the same password on multiple sites (I do it for all but the higher security sites), and therefore if you can get one password from them you can log into other accounts on other sites.

It also prevents the real password from being stored, even temporarily, on your site, and that may provide a little extra security if your site is compromised.

So, while I'd consider user-side hashing to be potentially a good things, it isn't worth going to much extra trouble.

And, as others have told you, don't roll your own security. There's far too many things that can go wrong. You won't notice them nearly as fast as a practiced bad guy will.

David Thornley
  • 54,186
  • 8
  • 87
  • 153
  • `It's also not really secure, since the bad guy can presumably load your login page and examine the Javascript or Java deployed.` Good security shouldn't depend on the attacker not knowing your algorithm. So, this point is spurious. It's the key you're trying to make harder to determine, not the algorithm. The attacker can also look up source code implementing SSL. Doesn't mean the attacker can break SSL. – Parthian Shot Jun 25 '14 at 20:48
14

The hash is identical to the password from a security POV in the scenario you describe: if I intercept the hash, I don't need to know the password, I can just send the server the hash I intercepted.

Authentication protocols go to some length to avoid this problem; security is hard, and you are best off selecting and implementing a well-understood protocol rather than rolling your own.

If your traffic is going over SSL, you're safe from interception and hashing gives you little extra benefit.

moonshadow
  • 75,857
  • 7
  • 78
  • 116
  • 12
    The only way it's not equivalent is that the user's password--which he may use for multiple accounts--is not in the wild. – Lucas Oman Sep 04 '09 at 16:27
  • 1
    @LucasOman Sorry but a single basic hash does nothing to protect a password and it provides a false sense of security. Tools like hashcat can run billions of basic hashes per second on commodity hardware. The only way to make it provide any protection with a client side hash is to run a full BCrypt/PBKDF2 with tens or hundreds of thousands of iterations, like we do to store passwords on the server. That's silly because the resulting hash is still the password as far as the server is concerned. Just use SSL. – Tito May 20 '14 at 17:43
  • 1
    @Tito "a single basic hash does nothing to protect a password" That's a blatant lie. Hashcat is doing a brute force attack, which means that if the password is any kind of length the attacker won't be able to guess it. So, if the same, long password is being used across multiple services, an attacker with only the hash can only use it on the service accepting that hash. And if every site that did this used the same hashing algorithm, but a different, vendor-specific nonce, then you could virtually guarantee that the hash would only be useful on one site. – Parthian Shot Feb 14 '15 at 22:53
12

Yes, you should.

IEEE had a data breach in which 100K emails and passwords were exposed from a weblog.

http://ieeelog.com/

Obviously, IEEE should not have exposed their weblog! But if they had hashed the passwords at the client side, this wouldn't have been nearly as bad.

As the first answer states, you should use a nonce. If you use a long enough nonce (e.g. 128 bits), you don't really need to worry about reuse, as the server will never ask for the same nonce twice (assuming correctly seeded CRNG, etc.).

user1700819
  • 121
  • 1
  • 2
5

No, hashing at the client does not protect the password 'completely'. When one opts to hash the password at the client, then the digest submitted to the server, essentially becomes the password. This is not a problem in itself if SSL is deployed.

However, this scheme ends up creating more problems than it solves. If the server were to compare the hash submitted by the client with a stored hash in the database without performing any further cryptographic operations (especially hashing the input data), then the password is stored in clear text for all practical purposes. Any person with access to the stored hash can re-submit it to the server and gain access to accounts.

In simple terms, if the submitted hash (which is the same as the submitted hash) were to leak via any other vulnerability within the application (via SQL injection, for instance) then the application has a vulnerability where in it protects the passwords inadequately.

If the underlying vulnerability must be fixed, then it is necessary to treat the submitted hash as a password in clear text, which should then be hashed (with a salt preferably) before comparison with a stored hash.

Vineet Reynolds
  • 72,899
  • 16
  • 143
  • 173
  • 2
    `hashing at the client does not protect the password 'completely'` Well, nothing protects the password _completely_. If your attacker is willing to kill a child every minute until you let them post on your wordpress blog, assumedly you'll eventually let them upload all those cat pictures. The point is does it protect the password _more_, to which your answer is apparently 'no'. `the password is stored in clear text for all practical purposes` No, it's not. The **authentication token** is in plaintext, but the **password** is hidden. – Parthian Shot Jun 25 '14 at 20:53
  • I know the distinction between authentication token and password might seem pedantic, but if I'm someone who habitually uses active nuclear launch codes as passwords, or I'm Rush Limbaugh and my password is "I killed a little girl in 1993 and this is my legally binding admission of guilt", the difference is pretty important. – Parthian Shot Jun 25 '14 at 20:55
5

I think it makes sense in one circumstance; you don't want to even know the client's plaintext password. If you hash at the client side, then salt and iteratively hash that hash the same way you would a plaintext pw. Other than that, its kinda silly.

George Griffin
  • 434
  • 4
  • 12
4

Just make sure that you are sending your password through a secure channel (SSL). If the client can have an application private memory read, then most likely they have bigger problems, like for example a keylogger.

Esteban Küber
  • 33,970
  • 13
  • 78
  • 96
1

You'd be much better off if you used the Secure Remote Password protocol (SRP). It was designed for this.

Jeff Moser
  • 18,820
  • 6
  • 58
  • 83
0

I can give you different kind of approach If you have not SSL you can hash password on client side and again it hashed on server side using another hashing method and store them on database and when user login with password do the same process and match double hashed password with stored hashes

Alupotha
  • 8,014
  • 4
  • 43
  • 45
  • The danger there, and what is mentioned in other comments to other answers, is the [replay attack](http://en.wikipedia.org/wiki/Replay_attack) – George Griffin Apr 11 '15 at 00:50
  • 1
    @George'Griffin - How is a replay attack specifically relevant to obfuscating or encrypting the transmission? Wouldn't it also apply to plaintext transmission, except with that case, the precise password could be more quickly or even inadvertently compromised? – groovenectar Oct 14 '15 at 14:08
-2

Hashing on the client side opens up another huge hole: you may expose the hashing algorithm. You don't say whether this is web-based (client=JavaScript) or thick-client, but you're giving them more information. Given the channel is secure, you don't have to worry about the clear text password being sniffed.

Besides, if your hashing algorithm requires a salt, you would be exposing your salt, which means if they ever got access to the database, they would be able to decrypt every password.

dj_segfault
  • 11,455
  • 3
  • 26
  • 35
  • 6
    Not true. 1) Security should never rely on hiding the algorithm which is being used. 2) Even if you know the salt, its very very difficult to de-crypt the passwords (provided they are encrypted using the standard ways) unless you got a rainbow table of that 'salt'. – sojin Jun 11 '11 at 11:05
  • 2
    This answer seems to misunderstand the function of a salt. If you are using the same salt for every password, then you're doing it wrong and you might as well not be using a salt at all. – Nate C-K Jan 23 '14 at 17:41