32

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...

In general: What is the rule of thumb for size of salt?


Related:

What should be used as a salt?

What is a good enough salt for a SaltedHash?

2
  • Forgive me but I thought scrypt generated the salt for you automatically. Commented Apr 23, 2014 at 7:25
  • 1
    @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. Commented Apr 27, 2014 at 17:16

2 Answers 2

37

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.

5
  • 3
    Salts must be far more than unique. Salts protect against making a rainbow table, or some other form of pre-computed attack. If you never would have more than 10,000 users, a salt of 32 bits would be sufficient. But yet it'd be trivial to pre-compute all the values of a 32 bit salt. Commented May 1, 2015 at 16:59
  • 5
    @SteveSether Inflating your password dictionary by 4 billion times is not so practical. Thus, even the hypothetical small salt has achieved the design goal of significantly increasing the attack complexity.
    – MickLH
    Commented Jan 5, 2017 at 17:01
  • 1
    96 bits is still beautiful.
    – MickLH
    Commented Jan 5, 2017 at 17:03
  • 1
    When you say "a salt is not exactly the same as an Initialization Vector for symmetric encryption", can you explain a bit more why that is? This is something that I've been wondering about, since they seem to do the same thing. Commented Apr 21, 2021 at 20:49
  • 1
    If uniqueness is their one job, a sequence number would offer more uniqueness than a random number since there is no chance of a conflict.
    – Jonathan
    Commented Apr 1, 2023 at 14:46
9

"It should be at least eight octets (64 bits) long." from: http://www.ietf.org/rfc/rfc2898.txt

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .