I want to hash passwords for security, but strong bcrypt by nature eat up a bit of resources of the server. So I was thinking to do the encryption on the client side. This would prevent the password from being known in the case the off chance server is hacked.

Client JS encrypts password via bcrypt -> sends to server via TLS -> stored in DB as salted SHA256/512 HMAC

Of course there is a limit of login attempts per account and per ip. And use of captcha.

Also, any sensitive account changes or the like requires the user confirms it in their email.

The primary goal here is mostly to prevent in the off chance the server is hacked, that the passwords would be leaked for other services the user may share passwords. While not wasting much extra server resources.

I am the only one who has access to the database. And obviously once the system is hacked, more than likely everything would be compromised so they can make people enter their plain text passwords by tricking them. (albeit a database can be leaked via an automated hack exploit, where as doing the above would require a targeted hack)

The main goal here is that many places are now passing laws that can hold you accountable if your database is leaked if you did not provide enough security for the user's data. And I want to know if encrypting bcrypt server side offers any realistic advantage over client side bcrypt + server side hmac?

  • In your implementation, where would the salt (as needed for the client-side bcrypt hashing) be stored? If on the server, then you would need to work out some protocol for the client first getting the salt for the user from the server (and at that point, this begins to look very much like PAKE/SRP). If on the client, then this presents usability issues with clients logging in from different browsers/devices, etc. See also security.stackexchange.com/questions/254820/… which seems similar.
    – mti2935
    Nov 15, 2021 at 23:26
  • @mti2935 Since the logins are emails, I would check if the email is valid and send the client a salt (of course if the email is invalid, I would send a fake salt not to reveal if a user is in the db or not), then have it verified on client end. I'll look into SRP, it looks similar, but from the sounds of things it sounds more like a TLS replacement for passwords. But I'll look into it in more detail. Thanks. Nov 16, 2021 at 0:05
  • @mti2935 I can also technically use a hash of the email as a salt. It's not like the salt isn't stored anyways in the bcrypt hash. This way, there would be less back and forth. when a user changed their email, I would ask for the password anyways and can both verify the old hashed password and create a new one. Nov 16, 2021 at 1:00
  • See security.stackexchange.com/questions/69421/… for some interesting reading on using usernames on salts. If you are going to query the server for the user's salt, then this looks a lot like PAKE/SRP. PAKE/SRP is often run over TLS, and offers many benefits aside from protecting against user database breaches (e.g. protection against MITM attacks, mutual authentication, and more). See security.stackexchange.com/questions/242811/…
    – mti2935
    Nov 16, 2021 at 2:03
  • @mti2935 Yes, I understand usernames aren't a good choice cause too many share the same username. Emails though are more unique though as no 2 users share the same email. And if the email is hashed alongside even a fixed value, it should result in a completely unique salt that no other site shares. I will play around with SRP and see, especially on how much impact it has on server resources, and how reliable the module for it is (I am upgrading an really old code here written in Perl, there is an SRP perl module, but it hasn't seen any update in 4 years) Nov 16, 2021 at 2:57


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.