I will be using scrypt to store passwords in my application. As such, I'll be using SHA-256 and Salsa20 crypto primitives (with PBKDF2).

Having that in mind, how big salt should I use?
Should it be equal to the size of SHA-256 output: 256bits or should it be equal to number of bits I'll take from this password stretching function: 512bits?

Considering that SSHA as used by OpenLDAP has only 32bit salt and Linux crypt() uses 48bit salt my salts would seem fairly large...

Forgive me but I thought scrypt generated the salt for you automatically.
–
DarcyThomasApr 23 '14 at 7:25

@DarcyThomas an implementation of scrypt may generate salt automatically for you but it has to have a source of entropy to generate it from. In languages like Java you have such cryptographically safe source, in pure, standard, portable version of C you don't.
–
Hubert KarioApr 27 '14 at 17:16

2 Answers
2

Salts must be unique; that's their one and only job. You should strive, as much as possible, to never reuse a salt value; the occasional reuse is rarely critical but should still be avoided). With reasonably designed password schemes, there is no other useful property in salts besides uniqueness; you can choose them however you want as long as you do not reproduce the exact same sequence of bits. Uniqueness must be understood worldwide.

(With badly designed password hashing schemes, the salt might have some required additional properties, but if you use a badly design password scheme you already have bigger problems. Note that a salt is not exactly the same as an Initialization Vector for symmetric encryption, where strict requirements like unpredictable uniform randomness typically apply.)

A common way to have more-or-less unique salt values is to generate them randomly, with a good generator (say, one which is fit for cryptographic usages, like /dev/urandom). If the salt is long enough, risks of collisions (i.e. reusing a salt value) are low. If you use n-bit salts, chances of a collision become non-negligible once you reach about 2n/2 generated values. There are about 7 billions people on this planet, and it seems safe to assume that they, on average, own less than 1000 passwords each, so the worldwide number of hashed passwords must be somewhat lower than 242.7. Therefore, 86 bits of salt ought to be enough. Since we kind of like so-called "security margins", and, moreover, since programmers just love powers of two, let's go to 128 bits. As per the analysis above, that's more than enough to ensure worldwide uniqueness with high enough probability, and there is nothing more we want from a salt than uniqueness.

Uniqueness can also be ensured through other means, e.g. using as salt the concatenation of the server name (the worldwide DNS system already ensures that everybody can get his own server name, distinct from that of anybody else on the planet) and a server-wide counter. This raises some practical issues, e.g. maintaining a counter value which does not repeat, even in the case of an ill-timed server crash&reboot, and/or several front-ends with load balancing. A random fixed-length salt is easier.