5

In Linux we have the salt just next to the password hash in the /etc/shadows file.

I always hear that salt value prevents hashed passwords from being cracked by brute force methods. But if somehow we get the shadow file we can inject the salt in the algorithm and still use a brute force method, right?

I'm not considering the time spent, just the general idea. I know that brute forcing a SHA256 or SHA512 hash will take forever.

S.L. Barth
  • 5,486
  • 8
  • 38
  • 47
Kruncho
  • 403
  • 5
  • 10
  • I suggest you read this https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords. It's much more in depth than your question, but it gives a great overview of password hashing functions including salts and peppers. – Chris Murray Jun 09 '15 at 08:30
  • 1
    TL;DR, salts ensure that all passwords are globally unique to force an attacker to break each individually, thus preventing any reuse of work. They are not intended, expected, or required to be kept secret. That said, don't hash your own passwords; use something like bcrypt. – Stephen Touset Jun 09 '15 at 08:45
  • If you like pseudocode, please look at [this excellent answer](http://security.stackexchange.com/a/89540/76768) that shows plain hashing compared to hashing with unique salts. You will see the additional amount of effort needed clearly. – mucaho Jun 09 '15 at 11:00

5 Answers5

10

Salt doesn't have to be secret. However, it MUST be unique for each password. Consider this : if all your passwords are hashed with the same salt, then an attacker who gets access to your database "only" has to compute H(pwd+salt) for each possible pwd value and he gets all your passwords. If the salt is unique however, the same operation will only get him ONE password, the one associated with the salt he just tried.

ero
  • 504
  • 2
  • 6
9

A salt does not make brute-forcing a single password any harder, as you correctly pointed out.

Without a salt, an attacker could build one single rainbow-table, and (s)he would get all passwords at once. With a salt, the attacker has to build a rainbow-table for exactly this salt, so he cannot reuse already existing rainbow-tables. When you use a different unique salt for each password, then an attacker would have to build a rainbow-table for each password. This does not make sense, after finding a match there is no advantage to finish this rainbow-table, brute-forcing is cheaper.

With a unique salt per password, one cannot use a precalculated rainbow-table to get several passwords at once.

This also answers the question, why the salt doesn't need to be secret. Algorithms like SHA-* are not appropriate to hash passwords, because they are too fast and therefore can be brute-forced too easily. Use them together with PBKDF2 or use Bcrypt/Scrypt, which offer a cost factor.

martinstoeckli
  • 5,149
  • 2
  • 27
  • 32
4

Hashing the password with a salt makes it much harder for an attacker to use a precomputed list of hashes (aka rainbow tables) to run the discovered hash against.

It will force him to compute the hashes again for any salted password hash he wants to crack.

Orny
  • 294
  • 3
  • 7
2

You're right. Salting really makes password hacking more difficult for non-trivial passwords, but if some users use common passwords, can still hack the password by brute force a few thousands times.

If the salt is public/stored together, like your case, it is just used to prevent pre-computed password hashes lookup, i.e. rainbow table.

Thus, if for similar algorithms in web applications, I would suggest may also prepend a constant application-specific secret key to the users' password, before hashing by the salted algorithm. Of course if your app secret key is leaked, then this security enhancement is vanished. Thus, I store that secret key in code to separate it from the password hashes database. (That is unachievable in Linux shadow file)

Further remark: the main point of adding the extra "secret key" (or pepper) is: even the hash of a simple password cannot be brute force just few thousand times to crack it (they are as hard as complicated passwords to brute force), given that the hacker only know the password hash, but not yet able to see the secret key in your code. (Meanwhile, it doesn't guard the online website password brute force attempts, it guard the offline attempt to crack the hash itself only)

Johnny Wong
  • 201
  • 1
  • 4
  • 1
    A salt is always public (at least, as much as the hash value). We do not rely on a salt value being secret to protect our hashing function. The "application-specific secret key" you mention is known as a "pepper", it's merits are debatable at best. It may add some security where your DB is compromised, but not the web application. – Chris Murray Jun 09 '15 at 08:25
  • 1
    Thanks for introducing me the word "pepper". Didn't aware that term before. :) – Johnny Wong Jun 09 '15 at 08:29
  • @Chris Murray Thanks for comment. Of course my "pepper" method is not perfect, but if both our database, and web application (two layers) is compromised, I wonder if there is any other economy & good solution that is near-perfect to makes hacker very difficult to recover passwords, even all our system is compromised?? One could be suggested if it exist. – Johnny Wong Jun 09 '15 at 08:46
  • What I introduced is use salt & pepper together. I would listen any reason for downvote, please. – Johnny Wong Jun 09 '15 at 08:50
  • there is no perfect solution, but read the question I linked to in the comment on the question. Thomas does a great job of outlining what best practice is and why. Wasn't my downvote, btw. – Chris Murray Jun 09 '15 at 08:51
  • @Chris Murray Thank you very much for detail info. :) – Johnny Wong Jun 09 '15 at 09:06
0

It makes a dictionary attack a lot more difficult, if the salt is created in a smart way. For example, bcrypt uses a 128 bit salt.
A salt is usually generated randomly. If it was derived only from the password or the password hash, it would indeed not add much security. If it is generated in a way that cannot be predicted by the attacker, it significantly increases the search space - making the brute force attack require a lot more brute force.

Keep in mind that even in a brute force attack, an attacker will still try the predictable passwords (like "pa$$w0rd") first. Assuming an unpredictable 128 bit salt, the attacker now has to try up to 2^128 more possibilities to crack the hash for "pa$$w0rd"+salt. On average that will be half of 2^128 possibilities before the attacker succeeds, which is still 2^127 more possibilities.

S.L. Barth
  • 5,486
  • 8
  • 38
  • 47
  • 1
    A salt is non secret. The attacker has no need to guess the salt, as it's stored right along side the hash. The salt is only meant to protect against a precomputed list of hashes. – Chris Murray Jun 09 '15 at 08:20
  • 1
    @ChrisMurray Precomputation isn't needed. Brute force against a list of hashes will have a major advantage if they are unsalted regardless of any precomputation. – kasperd Jun 09 '15 at 10:26
  • @kasperd, You mean that if two people have chosen the same password they will have the same hash without salting, right? And therefore cracking the first one will also give you access to the second one. This is still precomputation. You have precomputed the first one, thereby given you access to the second one. – Chris Murray Jun 09 '15 at 10:36
  • @ChrisMurray I didn't say the hash or salt were secret. Even when using a precomputed list, the salt increases the search space by 2^(length of salt in bits). Requiring considerably more resources from the attacker. – S.L. Barth Jun 09 '15 at 10:41
  • @S.L.Barth Um, no it doesn't. The attacker knows the salt (unless it's secret). There is no entropy, because the attacker is not guessing at the salt. The attacker simply has to use the salt that you've given them. – Chris Murray Jun 09 '15 at 10:50
  • A salt can, but shouldn't have to be secret. As long as it's unique for every user, a rainbow table attack wont help vs multiple users, and is therefore void. If a salt is based purely on the password, it will NOT be unique for every user, and does not protect against rainbow tables. – Dorus Jun 09 '15 at 12:18
  • @ChrisMurray It doesn't make any difference whether two users have the same password. An attacker can consider one password at a time (starting with the least entropy). After each guess has been hashed the attacker can instantly tell if any of the users have that password. – kasperd Jun 09 '15 at 15:29
  • @S.L.Barth The attacker knows the salt, so the search space doesn't grow exponentially with the length of the salt. It does however grow with the number of users. Breaking the passwords of a million users takes a million times as long as breaking the password of one user. But that is only true as long as no two users have the same salt. So the salt has to be long enough to guarantee that it is unique. And since a long salt is cheap you may as well go for a salt which is long enough to be unique across all passwords ever chosen by every user on every system. – kasperd Jun 09 '15 at 15:34