0

This question already has an answer here:

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?

marked as duplicate by Steffen Ullrich, S.L. Barth, techraf, schroeder Oct 11 '16 at 6:42

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

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.

  • 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 3:10
  • So should I hash server side or client side? – Tobiq Oct 11 '16 at 3:20
  • I'm confused, some places say hash user side, some places say otherwise. – Tobiq Oct 11 '16 at 3:34
  • 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 Oct 11 '16 at 4:47
  • 1
    @Tobiq No, hash on server side ONLY! – Thomas Stets Oct 11 '16 at 9:17
1

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?

You take the data they send you, hash it using the unique salt stored in your database next to their username, and compare that to the salted-hashed password stored in your database next to their username. This is an absolute MUST for security.

It's fine if they hash their password before sending it to you (assuming they always do that; probably because the client does it automatically). This is a nice step if you are trying to protect your password-reusing users, but the hashed-before-it-gets-sent-to-the-server password is really just acting as a pseudo-randomly-generated password.

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.

Hashes aren't "slow" by any definition for users. They take a very small fraction of a second. Unless you're getting hundreds of login attempts per minute you shouldn't need to worry about the server load from hashing passwords.

Hashing the password on the mobile doesn't do anything for the security of this account (all it does is keep the original password from being transmitted over the wire, which is only terribly useful if the wire can be intercepted and the user is sharing passwords between services (in which case the user's other accounts are now compromised). If the user isn't reusing passwords and the wire can be intercepted then it doesn't matter if the original password or a hashed version is being sent, because what is being sent is what's used to authenticate the user to this server).

When we talk about a hash being used to slow down brute forcing, it's with the assumption that the attacker stole your database (containing the salts and hashed passwords) and is now trying to hash common passwords against each of the salts and looking for matches. A hash that's slow because it's happening on a mobile doesn't do anything to protect the user, since the attacker will undoubtedly be using faster hardware. A slower hashing algorithm and/or one with more rounds of hashing means the attacker has to wait a tiny tiny bit longer for each crack attempt. So a slow hash that takes, say, 0.0001 second instead of 0.00001 seconds would mean they could only try one-tenth as many hashes in a given amount of time. Note that if you hash the user's password at the client and then again on the server, that's just adding one round to the overall hash time (presumably the attacker grabbed a copy of the client code and has noticed that the passwords get hashed before being submitted and has written their attack code to take that step, too).

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?

The hashing on the mobile side is still pretty fast, like I said, so it shouldn't have a noticeable delay for the user.

The hashed password becomes the password used to access your server, so to your server it just looks like everyone is really good at generating random passwords. But that's why you still need to hash the "password" they sent you with a salt (and that will match what you've stored in your database) because otherwise once someone gets your database they can just directly send those hashes to you (bypassing the hash function in the client) to authenticate to your server.

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.

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.

-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

  • Will the client side hash match the server side hash?? – Tobiq Oct 11 '16 at 3:22
  • If they use the same hash algorithm and salt, yes. – David Oct 11 '16 at 3: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 Oct 11 '16 at 4: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 Oct 11 '16 at 4:57
  • 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 Oct 11 '16 at 18:30

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