1
$\begingroup$

I'm working on a web application where passwords must be hashed on the client before it can be send to the server. This is because the user's raw password is used for cryptography purposes and can't be sent anywhere.

My initial thought was to use a SHA algorithm, but then I was wondering if maybe using something like argon2 would be better. Because I have to validate the password on the server without having access to the raw password, I have to use the same salt when using Argon2.

Note that I will properly hash the client-side hashed password on the server again before saving it into the database. But the server will have access to the passwords directly from the client, so in case the server gets hacked and they change the code, they still won't have access to the raw password.

So my questions:

  1. Is having access to many passwords that are hashed with the same salt a security issue?
  2. Is using a SHA algorithm (like SHA-512) better in this case?
$\endgroup$
  • 4
    $\begingroup$ Can you tell us why you can't use different salts on the clients? Also using the same salt on all passwords means, when you see the hashes, you can identify duplicate passwords. $\endgroup$ – SEJPM Mar 27 '18 at 19:35
  • 2
    $\begingroup$ Why does the password have to be hashed on the client? At that point the hash becomes password equivalent. $\endgroup$ – mikeazo Mar 27 '18 at 19:42
  • $\begingroup$ hashing with the same salt is like having no salt at all $\endgroup$ – Richie Frame Mar 27 '18 at 19:48
  • $\begingroup$ @SEJPM Because I need to validate login attempts on the server and as far as I know there's no way to validate whether a randomly-hashed password that's re-hashed with Bcrypt is valid. Or am I wrong here? $\endgroup$ – Basaa Mar 27 '18 at 20:01
  • $\begingroup$ @mikeazo The user's raw password is used for cryptography purposes and it can't be sent anywhere. $\endgroup$ – Basaa Mar 27 '18 at 20:01
0
$\begingroup$

To answer your explicit questions:

  1. Hashing many passwords with the same salt is definitely a security issue. The whole point of a salt is to never hash different passwords¹ with the same salt.
  2. When passwords are involved, there is no way that a SHA algorithm can be more suitable than a password hashing algorithm such as Bcrypt or Argon2. Despite the similarity of names, hashing algorithms and password hashing algorithms have very different properties. Recommended background reading: How to securely hash passwords?

Now, on to your system design. It's difficult to tell exactly what you're doing, but there's probably something you need to change in your design. It may not need to be a drastic change, probably just making some changes to how you use the password and what information gets transmitted between the client and the server.

The salt needs to be unique, but it doesn't need to be secret. If the server needs to make a calculation involving the salt, either the salt should be stored in the server's database or the client should send the salt to the server.

The user's raw password is used for cryptography purposes

A password can't² be directly used for any cryptography purposes, for the same reason a cryptography hash can't be used for passwords. To turn a password into something that can be used for cryptography, such as a key, you need to apply a key stretching algorithm to the password.

Key stretching and password hashing are very similar. In fact, you can take a password hashing function with a suitably long output, split that output in two, and use one half as a key and the other half as a password hash. Knowing one of the halves of the output, you can't find the other half (unless you manage to guess the original password). You need to be very careful not to mix those two halves!

¹ By “different passwords”, I mean passwords for different accounts, or successive passwords for the same account. I'm not referring to whether the passwords happen to be identical character string.
² “Can't” meaning “your program may work but it will be grossly insecure”.

| improve this answer | |
$\endgroup$
  • $\begingroup$ I got the key stretching part covered, I have implemented that already. About the rest I'm confused. I explained that I'm re-hashing the hashed password on the server before storing it in the database. So the steps are client-side hashing -> server -> Bcrypt (or alike) -> database. If I use a random (even if stored in plain text) salt to hash the password on the client side there's no way for me to validate the password on the server side? $\endgroup$ – Basaa Mar 27 '18 at 20:25
  • $\begingroup$ @Basaa Ah. If you take the output of key stretching and hash that (with an ordinary hash), you can use the output of key stretching as a password from the server's perspective. The server doesn't care how the output of key stretching is generated since it never sees the input. $\endgroup$ – Gilles 'SO- stop being evil' Mar 27 '18 at 20:33
  • $\begingroup$ Okay. I'm sorry, I ain't no expert yet on this subject. I'm using Libsodium as my encryption library and am using it's crypto_pwhash as my client-side hashing function with a hardcoded / fixed salt. I know that this function is basically a key stretcher, but it needs a salt, so I provided it with a fixed one. Is this sufficient? $\endgroup$ – Basaa Mar 27 '18 at 20:47
  • 1
    $\begingroup$ @Basaa Use a random salt instead, which you generate the first time that password is used and store on the client. You can store it together with the encrypted data. $\endgroup$ – Gilles 'SO- stop being evil' Mar 27 '18 at 20:57

Your Answer

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

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