Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I recently had a comment made to me in an online discussion after I'd stated that randomness in a salt doesn't matter -- and I got the following response:

Salts may not have to be "secure," but the method of generation can matter. Using a cryptographic random data source helps ensure uniqueness and randomness in the salt data. Depending on the algorithm being used, the distribution of randomness in the salt can have bearing on the strength of the key.

Now, in most cases with a 22 character salt (in bcrypt for example) even with a prng the odds of generating the same salt twice are pretty small but its the second bit of that statement -- I'm not sure what that means and I certainly can't say its "wrong" without understanding it ....

So is this correct? Does randomness in a salt matter? Since salts are a known thing if someone's attacking a table of hashes, how can the quality of the salt matter?

share|improve this question

4 Answers 4

No. A salt is simply supposed to be unique so that you can't use an attack (such as rainbow tables) that computes a password hash once and uses that result against multiple password hashes.

If you're interested in making reversing the hash impossible without some secret knowledge, then append a site-specific password to the provided password (in addition to the salt) before hashing. A salt is stored with the hash, so making it hard-to-guess is pointless.

@Honoki:
If it's a global value or site-specific, then what you're thinking of isn't a salt, it's something else. That's not to say it's not a good idea, but it's not a salt. Typically an installation-specific secret is called a "site key" or "site password".

But salts are typically stored with the hash. For example, here's the current way Unix/Linux login passwords are stored. The password here is "foobar":

$5$BcjmguyyH.Qrf$ADRXhi/5xb.dYU67I.JdY57uoFjel/rqMqj14QJmTQ1
  • $ is the field delimiter
  • 5 is the hash algorithm specifier (in this case SHA-256)
  • BcjmguyyH.Qrf is the salt (not disguised in any way)
  • ADRXhi/5xb.dYU67I.JdY57uoFjel/rqMqj14QJmTQ1 is the hash
share|improve this answer
    
tylerl: that was always my understanding, thats why I was confused by the posters statement about "the randomness of the salt ..." –  erik Jun 16 '12 at 22:52
    
Why do you state that a salt is always stored with the hash? I can think of many scenario's where you wouldn't need to (e.g. one site-specific salt, a global value, as it were). In cases like that, you may want to opt for a not-guessable salt. –  Honoki Jun 16 '12 at 23:50
    
@Honoki: updated –  tylerl Jun 17 '12 at 5:37
    
Does the salt have to be appended with the password for it to be a salt? Most salts are stored in that manner, but i could see the salt being stored in another database and referenced when needed working well. In that case, the attacker has to compromise yet another database table to successfully crack the password, which might add another layer of security. At the very least, it will provide a form of security by obscurity. –  Terry Chia Jun 17 '12 at 9:46
    
@TerryChia A salt is just a little bit of randomness added to make sure you never get the same output twice. Hiding the salt isn't a bad idea, secrecy isn't the goal that salts are designed to achieve, so by doing so you're really combining two effects (a salt AND a site key) into a single element. I'm of the mind that your salt should be just a salt, and you should add a site key separately to get that benefit. But that's just my opinion. It helps to keep the components separate in my opinion. –  tylerl Jun 17 '12 at 19:43

In most password hashing schemes, salts must be globally unique. This means that, ideally, every single password instance in the whole world should have its own salt value, shared with none other (in particular, the same salt value should not be used in two distinct servers, and the salt must also be changed when a user changes his password).

Global, worldwide uniqueness is hard, because there is no central repository for allocated salts. An easy way is to rely on randomness: if you generate your salts from a cryptographically strong random generator (i.e. a "very good" generator) and if you make your salts long enough, then probability of a salt collision is very low -- sufficiently low to be neglected. Note that even if we aim at global uniqueness, the occasional collision is not immediately fatal, so we can live with that risk. 16 bytes is "long enough".

Any method which reliably ensures global uniqueness is good; but randomness is often the one which scales best, because it is purely local (no network-wide bottleneck).

Mutatis mutandi, this is the same issue than for UUID. "Version 4" UUID actually 122 random bits. Such UUID would be quite appropriate salts.

share|improve this answer
    
Since you mention UUIDs, version 1 or 2 UUIDs would also be suitable for salts, if implemented correctly (unique MAC address, and timestamps that do increment), because the UUID doesn't need to be unpredictable. However they would have no advantage over a random salt except on a device with no reliable entropy source. –  Gilles Mar 20 at 13:48
    
UUID can be more convenient in some programming frameworks: even when the system has a reliably strong PRNG, accessing it from within some software system may be harder than obtaining an UUID. Also, some systems may insist on a slow "initial seeding" process for strong PRNG, which would be useless for a seed. Basically, for a seed, we need something better than rand()-seeded-with-current-time, but not necessarily cryptographically strong, and UUID fit that niche nicely. –  Thomas Pornin Mar 20 at 16:11

Salts don't need to be unique. It's not an absolute requirement. However, the more different salts you use the greater the security so if they can be nearly unique that is good but don't worry about some people potentially sharing a salt due to poor randomisation.

Salt is used to prevent people using a pre-prepared rainbow table to crack your passwords. If you use the same salt on every password, you have foiled the pre-prepared rainbow table but it may be worth the cracker's time to create a custom rainbow table for your salted passwords. If you change the salt for some users, then you reduce the potential gain for the cracker in producing his rainbow table. For example, if you have two salts used randomly, then the cracker needs to create two rainbow tables. If you use 50 salts randomly, then the cracker needs to create 50 rainbow tables - getting more work. If you use a randomly generated salt for each user, the the cracker has to recreate a new rainbow table for each and every user. This is now so much work that the cracker won't bother trying and will use a different attack instead.

If you have randomly generated salts for every user, there is the possibility that two or more user's salts would be identical. This would only marginally affect the sites security. A cracker could now use a custom rainbow table to crack all the identical salted passwords. This might be a viable attack if the number of users with identical salts is large enough. If the number of identical salts is in the single figures, then it would not pose a big issue.

The value of the salt need not be a secret. Hiding the salt value is done by some people but mainstream password systems generally don't. Keeping the salt secret doesn't provide much additional security. The purpose of the salt is to ensure the password algorithms are not similar for each user and so block rainbow table attacks. Knowing the salt doesn't make the hashes any easier to crack so long as the salts are generally nearly unique.

share|improve this answer
1  
"but it may be worth the cracker's time to create a custom rainbow table for your salted passwords" No it's certainly not since direct multi-target attack against all hashes in the db is more efficient. Rainbow tables are useful if you don't have all hashes you want to crack at the same time or if you need to pre-compute but if you have a full database dump with a per-site salt, there is no reason to create a rainbow table. –  CodesInChaos Jan 3 '13 at 20:55

Given that the point of a salt is to prevent an attacker from precomputing hashes, I'd say it's mostly the uniqueness of the salt that matters, but randomness could be a factor for a particularly resourceful attacker - if your salts are very predictable, it's conceivable that an attacker could generate rainbow tables in advance of an intrusion attempt so as to speed up cracking passwords once they get the hashes.

Some techniques are little better than unsalted passwords - using a single salt for the entire password database means they only have to compute one set of hashes to crack the entire database, and using salts that are predictably derived from usernames (or are the actual username) means that an attacker can precompute hashes for user accounts they are interested in cracking (probably your admin accounts, privileged employees, moderator accounts, etc) even before they get a copy of the database.

In summary the salts need to be unique, and they need to be unpredictable for best security. Cryptographic standards of randomness probably aren't necessary, although they are a good way to guarantee unpredictability.

share|improve this answer
    
From your first paragraph, how likely is it for an attacker to pre-generate salts if it was randomly generated using a decent enough PRNG? What are the odds of that actually working? I don't see it as being very likely. I feel that a random salt that cannot be deduced from the username would work well enough. Randomness is not a really important factor. –  Terry Chia Jun 17 '12 at 9:49
    
@TerryChia A decent PRNG shouldn't be a problem. A very poor one is at worst entirely predictable based on some externally discernible factor, in which case the attacker can get a head start. –  Stephanie Jun 18 '12 at 12:32

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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