I'm a beginner to cryptography and looking to understand in very simple terms what a cryptographic "salt" is, when I might need to use it, and why I should or should not use it. Can anyone offer me a very simple and clear (beginner level) explanation please?

If you know of any references on the topic, those would also be useful in addition to your explanation.

I've edited your question to encourage explanations that should help, and the inclusion of references to help you out. I would however be inclined to take Jalaj's advice - definitely have a read around. If you can include in your questions what you're not understanding, you'll get a lot more out of the site. It is completely OK to quote the relevant parts of a reference you're not understanding and ask for clarification - in fact, that's better. The more precise you are about what you don't understand, the more we can help you :) Do feel free to edit in anything you specifically want covered.
–
user46Jan 30 '12 at 14:51

4 Answers
4

The reason that salts are used is that people tend to choose the same passwords, and not at all randomly. Many used passwords out there are short real words, to make it easy to remember, but this also enables for an attack.

As you may know, passwords are generally not stored in cleartext, but rather hashed. If you are unsure of the purpose of a hash-function, please read up on that first.

Now, what the attackers can do is to simply generate a list of common passwords and their corresponding hashes. Comparing the hashes that a site has stored with the table will, if common passwords are being used, reveal the passwords to the attacker.

A salt is simply added to make a common password uncommon. A salt value is generated at random and can be fairly small, the only purpose is to lower the probability that the hash-value will be found in any pre-calculated table. A common way to combine the salt and the password is to simply concatenate them, i.e. the stored hash value is Hash(salt||password). The common password password1 now magically becomes, e.g., 6$dK,3password1 and is very unlikely to be found in a table.

The salt can be stored completely in the clear in the database, next to the hashed value. Once the attacker has the database and wants to find the passwords, he needs to generate the pre-calculated table for each salt individually, a costly operation.

Yet another way to defend against this kind of attack is to slow down the attacker. This can be archived by iterating the hash-function many times, i.e. storing Hash(Hash(Hash(Hash…(Hash(salt||password)))…). Also, a pepper can be used, which is another random value concatenated to the password, such that the stored value is Hash(pepper||salt||password). The pepper is then not stored at all and therefore all possible values of the pepper need to be tested when trying to log in. Using 8 bits for the pepper give 256 possible values, which is very fast when the true user tries to log in. However the attack will work 256 times slower since all pepper values need to be tested for each password!

So essentially, when you have only one or 2 passwords stored in the database, the use of salt is effectively useless? What I understand is that this is only helpful when the number of passwords stored in the database is not small.
–
AbhinavChoudhuryJul 15 '14 at 12:26

1

@AbhinavChoudhury: No, it defends against rainbow tables - i.e. precalculated tables for a specific hash. An example: Take a password "password1". If you don't salt, you'd store HASH("password1") in your database. Now, if an attacker gets your records, and has precalculated HASH(*) for all 9-character passwords, he can recover the password. If you instead salted the password, HASH('somesaltforyou'||'password1') will NOT be in the attackers rainbow table (since it's more than 9 characters).
–
QuadrExAttFeb 25 at 9:17

It is a random number that is needed to access the encrypted data, along with the password.

If an attacker does not know the password, and is trying to guess it with a brute-force attack, then every password he tries has to be tried with each salt value.

So, for a one-bit salt (0 or 1), this makes the encryption twice as hard to break in this way. A two bit salt makes it four times as hard, a three bit salt eight times as hard, etc. You can imagine how difficult it is to crack passwords with encryption that uses a 32-bit salt!

No. Salt is usually assumed to be known to the attacker. In this case, past some low threshold, salt does not improve security.
–
fgrieuMar 7 '12 at 20:24

4

"Salt is usually assumed to be known to the attacker" -> Who is assuming this?
–
MikeMar 8 '12 at 14:45

@Mike: Who? Someone says "You should always assume the attacker knows the salt.". People at another page says "Salts are public", and later says "the salts are known, because that's the industry-standard use of the word salt." Another says "the salt are public knowledge, or at least should be treated as public knowledge.".
–
David CaryJun 11 '14 at 4:49

I'm going to attempt to answer a part of your question that has so far been neglected:

when I might need to use it and why I should/should not use it.

The short answer is that, as an amateur, you should not be using cryptography at a level that requires dealing with salts directly.

For instance, the bcrypt password hashing algorithm uses salts internally. But it doesn't expose that fact to developers using it — you simply pass the password to bcrypt (and optionally, a parameter that sets the "level of CPU effort" needed to generate the hash) and it returns the hash. When you need to validate if a password is correct, you pass bcrypt both the password and the previously-generated hash. It will indicate whether or not the password was the one used to generate the hash.

Do not take the advice given here and try to hash your own passwords using a salt. It is a low-level implementation detail, and if you find yourself working at a level where these sorts of things are needed, you are working at far too low a level of abstraction. Cryptography is very difficult to do correctly, and the Internet is absolutely littered with well-intentioned developers' completely insecure home-grown password hashing schemes.

That's good advice. But a comment like this can discourage someone from learning about cryptography. My ten cents' worth: Let this person go ahead and try to hash his own passwords, but warn against using it in an actual application
–
user7691Jul 18 '13 at 1:22

In the context of password creation, a "salt" is data (random or otherwise) added to a hash function in order to make the hashed output of a password harder to crack.

When might I need to use it?

Always.

Why should or should I not use it?

You should always use a salt value with your hash functions, for reasons explained below.

It is generally true people choose weak passwords, and it is certainly true there are gigabytes of publicly available rainbow tables chock-full of hashed values representing them. So when somebody creates an account on your service and selects a password to secure their identity, you can typically bet the password they choose will be 1) common, 2) unsecure and 3) available for cross-reference in lookup tables.

For example, the password Nowayin1 when hashed via MD5 is 6f367d65bc74b88e21fb9959487ffa3a and is obviously not a good choice. Even if it may look okay (and it doesn't), the fact the password's MD5 hash appears in open databases makes it worthless.

But that's just 128-bit MD5. What about something stronger, like SHA1 (160-bit) or even Whirlpool (512-bit)?

Same problem.

For example, P@$$word with SHA1 is 1e69e0a615e8cb813812ca797d75d4f08bdc2f56 and 1qazXSW@ hashed with Whirlpool is 0bf7545b784665d23b9c174ca03688a405f05b048e9d6c49bfc2721a1fa872bbd6576273d002e56d7c2a9c378efe607af36eea9d708a776e6f60ecb26e081cdf.

The root issue with all of these passwords, and billions more like them, is the fact their commonly-used hashes have become common knowledge.

A password salt changes that.

If a random value (the salt) were added to the user's selected password, then the SHA1 hash 1e69e0a615e8cb813812ca797d75d4f08bdc2f56 would no longer reveal P@$$word as the user's password, because the hash value in the rainbow table would no longer match it.

And it wouldn't take much. A small 16-bit random value, for example, would yield 65,536 variants of each hashed value in the lookup tables. So a database of 15 billion entries would now need over 983 billion hashes in it to account for the salt.

So, that's the point of salting your hashes, to thwart lookup and rainbow tables. But don't hang your hat on a salted hash, because hackers won't waste much time using rainbow tables to figure out your passwords.

They'll use a five-server 25-GPU cluster system running Hashcat that can burn through 350 billion guesses per second cracking hashes for every conceivable eight-character password containing upper- and lower-case letters, numbers and special characters, in just under six hours. (And that was back in 2012.)

Techniques such as key-stretching that make hashes run slower can be used to offset the speed of such hardware, making dictionary and brute-force attacks too slow to be worthwhile, but hardware just keeps getting faster and faster.