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?

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

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.