Let's say I have a table of users set up like this:
CREATE TABLE `users` (
`id` INTEGER PRIMARY KEY,
`name` TEXT,
`hashed_password` TEXT,
`salt` TEXT
)
When a user is created, a randomly-generated salt is produced and stored in the database alongside the results of something like get_hash(salt + plaintext_password)
.
I'm wondering that if a malicious user gets their hands on this data, would they be able to use it to crack users's passwords? If so, what's a way that it could be prevented?
Salting was introduced (or at least made popular) in UNIX /etc/passwd file, which was world-readable. It is usually assumed that the salt as well as the encrypted password is known to the cracker. The purpose of the salt is the slow-down of the cracking process (since the same password won't map to the same encrypted string); it is not a secret in itself.
Assuming brute force attack of MD5,SHA1,SHA256 algorithms with GPU has a throughput greater than 1 billion of tries per second and SHA512 around 300M/s. If you use one of these algorithms, it will slow down hacker who used rainbow table (less likely), but it will not slow down hacker who used brute force attack (more likely). It will definitively not protect you, it just add a bit of security against outdated rainbow table (for these algo). A bit is better than nothing.
But if you use a strongest algorithm (eg. bcrypt), salt definitively worth it even if stored with hash because brut force is not feasible in term of time so rainbow make sense.
Have a look at this article and to summarize:
No, they're not useless.
So long as you use a unique salt for each row, then the salt will
preventslow down an attack. The attacker will need to mount a brute force attack, rather than using rainbow tables against the password hashes.As mentioned in the comments, you should ensure that the salt is a sensible size.
If an attacker knows the salt, the hashed password and the hash algorithm, then they can mount a brute-force dictionary attack (or rainbow attack).
This should give you an idea of how it works.
Lets say you want to encrypt a word "secret." After it is encrypted lets say it now looks like this 00110010.
If a hacker knows the encryption algorithm, they can create a table of words and their corresponding encrypted values. So they take the encrypted password "00110010" and find it in the table. Now they know that the password used to generate "00110010" was the word "secret." If you salt the word first, then a generic lookup table will be useless to the hacker. (A generic lookup table being a table of unsalted dictionary words and their encrypted values)
If you salt the word first ("saltsecret"), now the encrypted value will look different, and the hacker wont find it in the lookup table.
However, they can still start creating their own lookup table from scratch using your salt and eventually they will be able to reverse lookup passwords.
So to answer the question, if the passwords are sufficiently complex, it will take ages for the hacker to figure them out. You could change your salt every year and they would have to start creating a table all over again.
No, it's not worthless.
To successfully attack an account, an attacker needs to know the salt for that account (and every account's salt should be different), the hashing algorightm used, and the final stored password hash.
Given all of that information, you can write a program that keeps trying to hash different potential passwords until it finds one that matches.
If it's a bad salt (too simple or short), this can be made much faster because the program can use rainbow lookup tables to match the final stored password hash to the string that was hashed, and then just subtract the salt. But they still need all the information.
If it's a shared salt, this is bad because an attacker and use the salt to generate a rainbow table in advance that's good for any account on your system.