Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clientside password hashing

A friend of mine and me are having a discussion about whether we should pre-hash the passwords of the users of our webapp before sending it to our servers.

I know that there are multiple questions that already handle this topic but they're all about transferring it securely to the server. Our idea is not about the transfer security (we use SSL) we want to hash clientside to prevent that the "real" passwords reach our server.

The idea came as Twitter announced their bug that caused passwords to be printed to a logfile in cleartext.

We are currently discussing about whether this concept makes sense or not and how it affects the security of a password (in terms of Bruteforce) if we would hash it with SHA512.

TL;DR:

We want to hash passwords clientside to prevent our servers from getting them in cleartext (we use SSL for transfer).

Does this make any sense?
What algorithm would be best to use for hashing?

The hashed passwords would then serverside be hashed again with bCrypt.

like image 632
MysteriousPerson Avatar asked Nov 18 '18 23:11

MysteriousPerson


1 Answers

It 100% makes sense: in fact, the concept has been proposed by a number of people, but the difficulty is in implementing correctly. There are a number of pitfalls if you do it wrong, the most direct one is being vulnerable to "pass-the-hash" as @swa66 describes. To prevent that, you need to hash on both sides. The client-side hash should be slow (bcrypt, scrypt, argon2, or pbkdf2) whereas the server side hash should be fast (sha256).

EDIT: A number of people have down-voted this without understanding how this works, so I now include the basic details here (previously I only linked to how this works). The idea is to apply a slow hash such as bcrypt on the client side, and then a fast hash such as SHA256 on the server side. The fast hash is required to prevent pass-the-hash attacks. In the event of the database leak, an attacker either hash to invert the fast hash (impossible -- violates the one-way property of a cryptographic hash function), or brute force the preimage to the fast hash (impossible -- the size is the length of the output from the slow hash, for example 184-bits for bcrypt), or brute force the combination of the slow hash and the fast hash -- which puts the attacker back at the same position as if the entire computation had happened server side. So we have not reduced the security of password attacks in the event of a database leak by shifting the heavy computation to the client side.

I've surveyed a number of proposals like this in Method to protect passwords in databases for web applications. Additionally, I analyse the pros and cons and identify weaknesses that have not been identified before (account enumeration), and propose a unique way of doing this securely. The research is built off a number of sources, including:

  • Secure authentication: partial client-side key stretching… please review/criticize my idea
  • How to securely hash passwords? -- see section on Client Side Hashing
  • Client side password hashing
  • Discussion from various authors on Hacker News -- see comments from oleganza, mschuster91, crusso, etc...

You cite the Twitter example, and GitHub did similarly. When I wrote the paper above, the most prominent example for preventing a server from seeing the clear text passwords was Heartbleed, which I comment on in the paper (bottom of Section 1.3).

There has been subsequent follow up research by others identifying similar ideas -- Example: Client-Plus-Server Password Hashing as a Potential Way to Improve Security Against Brute Force Attacks without Overloading the Server. No one person deserves all the credit, but the main takeaway is yes it is a good idea if you do it securely, but you really need to understand the risks (it is easy to do insecurely if you have not read the research).

like image 153
TheGreatContini Avatar answered Dec 25 '22 10:12

TheGreatContini