Reputation: 1067
I've asked myself this question a dozen of times.
Is a password salt really necessary?
I couldn't find any good literature on the subject.
From a security perspective, do password salts help? If a database is breached, isn't the salt lost if the password is anyways?
Also, from a brush force perspective, if i ban IP's is there really any reason to store salts?
Upvotes: 3
Views: 757
Reputation: 24141
I would like to point out the real purpose of using salts. As explained in another answer, different salts lead to different hashes for identical passwords, but this is not the main purpose.
With using different salts for each password, you prevent building one single rainbow table to get all passwords at once.
As you wrote, the salt is not secret. To get a single password, an attacker could still build a rainbow table using this known salt. The problem is, that (s)he would have to build a second rainbow table for the second password, because it used a different salt. In other words, the first rainbow table cannot be reused to find other passwords.
Building a rainbow table to get only a single password doesn't make sense, it is easier to brute-force until you find a match, calculating the rest of the rainbow table is useless since you cannot reuse it. That's why we say, unique salts prevent rainbow table attacks, because brute-forcing is faster than working with rainbow tables.
Upvotes: 1
Reputation: 34426
Yes, you should always use salts. fortunately PHP is pretty clever. From this article:
If you use the default options for the
password_hash()
function PHP will generate a random salt for each password as it is hashed. The random salt is an additional layer of security which makes it exceptionally hard to crack any passwords. Even if two or more users use the same password each of their hashes will be different.
This gets you away from having to generate a salt and leaves the heavy lifting up to PHP. The verification piece, password_verify()
, uses the random salt placed in the hash to be able to test against a given password.
From the docs for password_verify()
:
Note that
password_hash()
returns the algorithm, cost and salt as part of the returned hash. Therefore, all information that's needed to verify the hash is included in it. This allows the verify function to verify the hash without needing separate storage for the salt or algorithm information.
Upvotes: 4
Reputation: 44851
You do need to salt because an unsalted hash is too easy to crack (using rainbow tables).
First, unsalted hashes result in more collisions. If two passwords used baseball
as their password, cracking one is enough to crack both. If both are salted, so that one becomes baseball#sd7#$j
and one is baseballL4&$h1
, that doesn't work.
Second, a password like baseball
or even *4kB$l!h_'
is going to be easy to reverse using rainbow tables if it isn't salted. This is because it's easy to create a rainbow table covering all passwords up to a certain length. If properly salted, though, *4kB$l!h_'
might be turned into *4kB$l!h_'H4Sj$8)@80-+2nm:W[oa}u#*4$lNamA{
or something else absurdly long. Generating a rainbow table for that is much, much harder.
With PHP, make your life easier and just use password_hash(). Whatever you do, do not roll your own security algorithms, especially with respect to password storage. You will get burned.
For lots more information, read Why are salted hashes more secure? You may also want to spend some time with OWASP's Password Storage Cheat Sheet and it's PHP Security Cheat Sheet.
Upvotes: 3
Reputation: 500
it does help against 'rainbow tables', which are precompiled hashes for known passwords. when you salt the password, they are useless, because the hash will be different.
Upvotes: 1