For my understanding salts in password hashes are used to prevent the precomputation of $plaintext \to hashvalues$ (rainbow tables).

I know from different threads, it is not necessary to keep the salt secret (ie it doesn't need to be encrypted), but nevertheless I was wondering 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 it's own random and unique salt. However to minimize the load on the server, the hash is calculated at client side. For this to be possible a function must exist, that allows an unauthenticated user to retrieve the salt of any registered user.

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.
–
fgrieuJan 15 '14 at 17:47

2 Answers
2

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.

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.

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...
–
ChrisJan 5 '14 at 7:40