15
$\begingroup$

From my understanding, salts in password hashes are used to prevent the precomputation of plaintext→hash values (rainbow tables).

I know from different threads that it is unnecessary to keep the salt secret (i.e., it doesn't need to be encrypted), but I wondered if it would be a problem by making it public.

The background of this question is the following idea:

For password authentication, a strong hashing function like bcrypt or scrypt is used. Every user has their own random and unique salt. However, to minimize the load on the server, the hash is calculated on the client-side. For this to be possible, a function must exist that allows an unauthenticated user to retrieve any registered user's salt.

$\endgroup$
4
  • 1
    $\begingroup$ It seems that this thread should cover your question? $\endgroup$ Jan 4, 2014 at 15:53
  • 1
    $\begingroup$ Salts aren't there to prevent pre-computation. They prevent multi target attacks. Rainbow tables are one particular example of multi target attacks, and a rather useless one. $\endgroup$ Jan 4, 2014 at 17:05
  • 1
    $\begingroup$ Just like the similar question Is the salt value a secret or can it be stored in cleartext just like the IV?, this seems to be a possible duplicate of Can you help me understand what a cryptographic "salt" is? $\endgroup$
    – e-sushi
    Jan 4, 2014 at 19:16
  • 1
    $\begingroup$ It would seem that if "to minimize the load on the server, the (bcrypt or scrypt lookalike) hash is calculated at client side", the protocol is vulnerable to passive eavesdropping or disclosure of the hashes, followed by client simulation, unless encryption is used to transfer the hash from client to server; and even with that encryption, that the protocol is vulnerable to MITM, unless there is an initial secret key or public-key certificates. $\endgroup$
    – fgrieu
    Jan 15, 2014 at 17:47

2 Answers 2

23
$\begingroup$

The usual answer is that a salt can be make public; if that was a problem, then the salt would not be called a "salt" but a "key".

In some protocols, unauthenticated obtention of the salt is the norm, and is not considered to be a problem. E.g. with SRP, a password-authenticated key exchange, where any salting and hashing must necessarily occur client-side.

Some people have argued that if the attacker can know the salt in advance, then he can do precomputations. This is a gain for the attacker only in a specific scenario, where the context is such that the attacker must be able to crack a password within a very short time frame (say, one second) but has a few weeks to prepare for his one-second attempt, for a specific target user. This is a fringe scenario which very rarely applies.

$\endgroup$
7
$\begingroup$

Thomas Pornin has already answered your question accurately, but I'd like to add a strong warning to the discussion.

You should probably not be computing password hashes client-side.

In the most naïve approach, completely eliminates most of the value in password hashing. By computing hashes on the client and simply comparing their equivalence server-side, you are now effectively storing the "password" used to log in directly on the server. This will allow anyone who gains read access to the hashes table to impersonate any user.

Again in a naïve approach, with simple string comparison, you now open yourself up to timing attacks. Standard language string comparison operators short-circuit their evaluation at the first differing character. This is great for performance but bad for cryptography, since a malicious user can use this leaked timing information to iteratively "guess" the password. Recent work has shown that this type of attack is viable, even over typically internet latencies.

Third, in the event that this is for authentication to a website, this means you'll be using crypto in the browser, which is still a very long ways from being able to ensure security assurances we take for granted when doing local computation.

That said, there are ways of constructing protocols that allow for client-side computation of password hashes for server relief. The new Catena password hashing candidate has this concept built in, although it hasn't yet been thoroughly vetted by the cryptographic community. SRP, as mentioned by Thomas, is another example. However, it's not something that one who is not intimately familiar with cryptography should be attempting on their own, as (with most things in cryptography) there are many pitfalls and traps for a novice to unknowingly overlook.

$\endgroup$
4
  • $\begingroup$ Hi Stephen, thanks for your input and the additional warning. Your points are absolutely valid! You may be right that introducing something new, just to save a few CPU cycles, isn't a good idea... $\endgroup$
    – Chris
    Jan 5, 2014 at 7:40
  • 1
    $\begingroup$ @Stephen The advantage of calculating a slow hash client-side is that you can consequently simply use a fast hash for storing the hashed password in a database. This will be less resource intensive for the server, and the client's plaintext password will be even more secure, which is the main concern since in this scenario the database has already been breached. So my suggestion is to let the client do N iterations, and then let the server do the last iteration. $\endgroup$
    – Yeti
    Aug 6, 2018 at 7:30
  • $\begingroup$ I'm aware of the advantages, and even mention "server relief" features of some newer password hashes. However, I stand by my assertion that it's something you should not wire up together on your own without a solid grasp of cryptography, because there is a high risk of introducing serious vulnerabilities in doing so and because you will often have clients that are severely underpowered compared to your server when calculating password hashes. $\endgroup$ Aug 6, 2018 at 19:13
  • $\begingroup$ You can compute hashes client-side in some scenarios. For example, if an encryption key for EE2E is derived from a password, you don't want to send the password to the server. In that case, you can send a hashed version of the password to the server and that becomes your authentication string. However, with this approach, the server should still hash the authentication string even though it is already a hash of the password. You never want to store an authentication string unhashed. The server will be storing a double-hashed version of the password: hashed by the client, then by the server. $\endgroup$
    – tedtanner
    Feb 3 at 19:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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