0

When a user logs into their account on my server, should they send their raw data to me, and then I bcrypt compare them, or are they supposed to hash and and I directly compare?

I ask this because someone posted about hashing on mobiles being slow. It would make send to take load off of the server, and make sense about the slowing down brute forcing, and also protect the user from snooping.

If I were to do this, wouldn't I run into the exact same problem - slow experience for mobile users, if so is it something that is just expected as part of logging in. Also, wouldn't the user generate a random hash which wouldn't match the one stored in my database?

Tobiq
  • 129
  • 1
  • 3
  • 2
    Possible duplicate of [https security - should password be hashed server-side or client-side?](http://security.stackexchange.com/questions/8596/https-security-should-password-be-hashed-server-side-or-client-side), [Client side password hashing](http://security.stackexchange.com/questions/23006/client-side-password-hashing) and [Why is client-side hashing of a password so uncommon?](http://security.stackexchange.com/questions/53594/why-is-client-side-hashing-of-a-password-so-uncommon). – Steffen Ullrich Oct 11 '16 at 04:34
  • 2
    If the server doesn't compute the hash, the hash cannot serve its purpose. The whole point of the hash is that even if an attacker somehow figures out the hash (say by compromising the database) they still don't know what to send to the server to access the user's account. If the hash is done client side, they do know what to send to the server -- the hash. – David Schwartz Oct 11 '16 at 08:26

4 Answers4

7

Users should not hash their passwords before sending it to a website. If the user hashes and sends the hashes credentials, the hash is acting exactly like a password and actually defeating the purpose of hashing. If an attacker steals your password hashes, they can just send those to your server to login.
You might want to read about Pass the hash attacks.

You must hash server side.

Stoud
  • 344
  • 1
  • 10
  • 1
    This is makes no sense. Both the hashed password or the password itself can serve as an _authentication key_. If an attacker can break your transport security then they can get your key and break the system. However, hashing on the user's end is a great idea because if this transport security is broken then the attacker only gets a hash instead of the user's password. – David Oct 11 '16 at 03:10
  • So should I hash server side or client side? – Tobiq Oct 11 '16 at 03:20
  • I'm confused, some places say hash user side, some places say otherwise. – Tobiq Oct 11 '16 at 03:34
  • @David if the server's database is comprised, attackers still cannot log in as you. My answer mainly assumes he was simply checking the hashed password from the client with a column in a database. If that is true, once the attacker gets into the database, a hash is useless. – Stoud Oct 11 '16 at 04:00
  • 1
    @David: the only thing proven by the client sending a hash is that the client knows the hash, not that the client knows the secret (the original password). If the transport layer security is broken, *it doesn't matter* if the attacker only sees the hash, because it's as good as the password. Better, in fact, since if the attacker got hold of the password, they would h ave to go to all the trouble to hash it with the correct algorithm and correct number of iterations before sending it. By hashing client side, you've done that work for them. – Craig Tullis Oct 11 '16 at 04:47
  • Hash on the server. – Craig Tullis Oct 11 '16 at 04:47
  • @Stoud: Exactly, if an attacker gets hold of the user account database in a system where the passwords are hashed client-side, they literally have an entire database of plaintext passwords. The hashes literally **are** the passwords. And there are a number of other reasons it's a bad idea. Who is going around teaching people that they should hash passwords client-side? They need to stop and really think the problem domain through. – Craig Tullis Oct 11 '16 at 05:01
  • I get it all now, hash on both side for most security - stop's user from getting hacked on every other site if they do get snooped, and also stops attacker from being able to log in if they get hold of DB. I'd need to do complicated stuff to make sure the user's hash is generated the exact same way as it would be on the database so that the hashed pass word would match - right? – Tobiq Oct 11 '16 at 06:58
  • 1
    @Tobiq No, hash on server side ONLY! – Thomas Stets Oct 11 '16 at 09:17
  • and use https instead of client side hashing? I read a post recommending double hashing even with https – Tobiq Oct 11 '16 at 09:58
  • @Tobiq: hashing on the server is the only thing that constitutes actual security for *your* system, regardless of whether you hash on the client. – Craig Tullis Oct 11 '16 at 14:33
  • What if I get sued by google for leaking passwords? – Tobiq Oct 11 '16 at 15:37
  • @ThomasStets Hashing once on the client's side and once on the server side is a good idea for various reasons, and does not compromise the security of the system: http://stackoverflow.com/questions/348109/is-double-hashing-a-password-less-secure-than-just-hashing-it-once – David Oct 11 '16 at 16:54
  • As long as you keep in mind that hashing *only* on the client side does compromise security. – Craig Tullis Oct 11 '16 at 16:56
1

This probably is a duplicate question. But I seem to keep seeing people recommend hashing passwords client-side while ignoring the true complexity of the issue and the near impossibility that anyone other than an information security scientist is going to get it right.

Bottom line, if you're making a web or mobile app, use HTTPS, configure it correctly and hash passwords on the server. Use bcrypt or scrypt, or if it's the easiest library for you to use, use pbkdf2. Those libraries are well designed. You're not going to invent better. BUT; if you use them to hash the password on the client, then send the hash, then you just made the hash your password. And if you're a mobile app developer, don't you dare set the flag in your HTTPS setup that tells it to skip checking the certificate chain.

It's dang complicated

Occasionally people mention using nonces, etc. Pass-the-hash, challenge-response authentication is nothing new. And various half-baked pass-the-hash schemes have been broken more than once. Consider Microsoft Lan Manager: LM, NTLM and NTLM with session security are all broken. NTLMv2 is apparently still secure, but it's the fourth in the chain. Microsoft has a few resources to throw at the problem. You're going to do better on your own? Kerberos is an example of a solidly secure authentication and authorization system with a lot of science behind it, which generates tickets and applies nonces and passes those around instead of transmitting the passwords.

But Kerberos is quite complex, and relies on computers having trust relationships with each other, and on computer clocks being in sync. It's complicated.

Half-baked attempts to pull off something similar between a web browser and web server, unless you're using the actual Kerberos protocol supplied by a competent, well-vetted vendor, are bound to end in tears.

Security is complicated, subtle and hard.

HTTPS is pretty darn good

Perfect? Maybe not, but current versions aren't broken. If the server is using a strong certificate (2048 bit key) and strong cryptography (TLS 1.x or greater), it's pretty darn solid. Sending your password via HTTPS is not the same as passing it in plain text.

Users should not use the same password for multiple sites

Really, seriously, if they do, it's ultimately on them. They've been warned so many times now. Even the Today Show anchors know not to use the same password on multiple sites now, for crying out loud.

Don't make the hash the actual password, believing you have implemented security

If you just hash the password on the client side and store that value in the database for comparison, then the hash itself is the password. Period.

Are you going to build a full challenge-response pass-the-hash system using nonces, and do it without introducing fatal bugs? Do you really have the time, budget and expertise for that?

There may still be a benefit for the user to hash their password before sending it. If the hash is intercepted, the attacker couldn't use it to log in to OTHER sites.

However; if that is done, and you don't have the chops to create the actual equivalent of Kerberos or NTLMv2 just for your app, it should be done completely independent of anything the server does or expects.

The server must compute the hash

Given all the preceding, the server still needs to hash whatever is passed to it (call it a hash, call it a password, same thing in this context), with salt that is stored on the server, completely blind to anything the client is doing.

In other words, if the client is sending a hash, great, but the server doesn't know or care. It's just a password.

You're not trying to prove that the client knows the hash value. You're trying to prove that the client knows the original secret (aka "the password").

So the server hashes the incoming password fresh each time, using salt that is stored on the server, and compares the computed hash to the stored hash. If they match, authentication has succeeded. Otherwise, authentication fails.

So very many things can go wrong if you try to be clever

You're going to get it wrong. You just are.

Imagine this example:

  1. Your client hashes passwords
  2. Your server stores said hashed passwords
  3. Attacker social engineers your CEO and steals your account database
  4. Attacker has a database full of passwords, not hashes, but actual passwords to actual accounts on your system.

Part of my point, I guess, is that the very question "Should I hash on the client or the server" belies the true complexity of the issue and far too many answers either fail to address the complexity at all, or gloss over it in ways that make a system less safe, not safer.

Craig Tullis
  • 1,483
  • 10
  • 13
0

Preferably both should be done, for different purposes.

  1. The user hashes their password with a salt specific to the website, to prevent the (possibly hacked or misconfigured) server stealing their password if it is too similar to the user's password on other websites.
  2. If you want better security, you can let the user hash their password more times, in case the server is hacked and the hacker was listening to the communication, and doesn't want announce the fact it is hacked.
  3. The server hashes the password with a salt before saving to or comparing with the database. So it won't be too disastrous if the database file is stolen.
  4. In addition, someone could hash the password using a slow algorithm, the earliest the possible, to slow down brute-forcing if the user is using a weak password.

But in practise, web browsers don't have the support to do 1 and 2 right. And for 1, even if a service doesn't use web login, it doesn't help much if only one service is doing that. So usually only 3 and sometimes 4 is implemented.

The user could use password management softwares to do 1. But most people don't. So sometimes we think 3 is also mitigating the problem 1 could solve. That may lead to some confusion.

For your question, it makes sense to move 4 to the client side. But 3 on the server side should be considered more important, and shouldn't be removed. In this case you are going to hash the password using a slow algorithm on the client side, and hash the result again using a fast algorithm on the server side. But I guess most services just don't use an algorithm which is that slow that is worth the hassle.

user23013
  • 660
  • 5
  • 11
-2

Already answered on StackOverflow. You want hash passwords on the client device because you want to touch the user's password as little as possible.

1) If the user ever complains about being hacked you can be confident that your server didn't give up the user's password, because your server never sees the user password.

2) You want to minimize the amount of time that a user's password spends on any storage device- yours or theirs. If you copy the plaintext to your device then their password exists in your memory and disks. You want to avoid this.

3) Transport security isn't perfect, so if you transmit the user's password you're making them vulnerable in the event of a compromise. If you hash on the client side then you ensure that a man-in-the-middle will only ever get hashes. This is enough to allow the attacker to break into your server, but your user is protected in the (common) event that they re-use their password on multiple sites and services.

4) You can address Stoud's concern by reversible-hashing the user's hash while in transport.

5) Then hash it again once it gets to your server.

https://stackoverflow.com/questions/3391242/should-i-hash-the-password-before-sending-it-to-the-server-side

David
  • 1,386
  • 8
  • 8
  • Will the client side hash match the server side hash?? – Tobiq Oct 11 '16 at 03:22
  • If they use the same hash algorithm and salt, yes. – David Oct 11 '16 at 03:55
  • Which means you have to publish the algorithm, and the number of iterations. TLS isn't perfect, but if it's broken and the bad guys get the password hash, it's game over anyway, because in this scheme the hash **is** the password--literally no difference at all. The hash is the password. This is wrong. It sounds like you're just trying to mitigate blame on the server side so you don't have to take responsibility if you screw up your TLS configuration. – Craig Tullis Oct 11 '16 at 04:52
  • 1
    The only thing that sending a hash to the server proves is that the sender knows the hash, not that the sender knows the original secret (the password). A bad guy could intercept the hash and use it to login just as easily as they can intercept the plaintext password and use it to log in. – Craig Tullis Oct 11 '16 at 04:57
  • @Craig Your second comment illustrates my point. Sending the original password is no more or less secure (for your system) than sending a hash of the password. But, sending the original password is more hazardous for your users than sending a hash of their password. If you hash on the client's side you do have to publish the hash and salt, but then you can hash again once it gets to the server and this step is secret. However, the whole purpose of a cryptographic hash is that it's difficult to reverse, so knowing the hash algorithm is of little value to begin with. – David Oct 11 '16 at 16:48
  • Nah, just hash in he client and pass that hash as the password. The server is then completely ignorant of whether the client is hashing or not, and the server hashes like normal. If you aren't implementing Kerberos, hashing on the client adds nothing to server-side security. – Craig Tullis Oct 11 '16 at 17:44
  • @Craig I understand that hashing on the client side doesn't increase server-side security, but it does increase user security. You have an obligation to your users to protect them as well as protecting yourself. – David Oct 11 '16 at 18:21
  • 1
    I believe we collectively have an obligation to provide complete and accurate answers to these kinds of questions if we're going to answer them at all. ;-) The fact is that overall security in the context we're talking about is ONLY served by hashing on the server. Hashing on the client can augment security, but it can also dramatically decrease security if it's done wrong. Far too many answers seem to come out and declare that hashing on the client is better, and a replacement, for hashing on the server, and that simply is not true. – Craig Tullis Oct 11 '16 at 18:30