I understand the need for hashing and salting, but I do not understand how storing the salt in the same (potentially compromised) database as the entire hash is secure. For example, a book I'm studying instructs to create a unique hash for each user (good) by randomly generating an integer and creating a byte[] using the RNGCryptoServiceProvider. That is all well and good, but in order to validate a user's password upon login, it will be necessary to read that unique salt from the database (or some other file). Is this a secure way of storing a salt?
A cryptographic salt is made up of random bits added to each password instance before its hashing. Salts create unique passwords even in the instance of two users choosing the same passwords. Salts help us mitigate hash table attacks by forcing attackers to re-compute them using the salts for each user.
Salting is important because it adds a whole new level of required computational power in order to expose the hash. By adding a salt, you effectively render any lookup table useless. Hashing a password is not 100% secure as hashing alone is not that difficult to break.
Using ten different salts increases the security of hashed passwords by increasing the computational power required to generate lookup tables by a factor of ten. If the salt is stored separately from a password, it also makes it challenging for an attacker to reverse engineer a password.
Since the whole purpose of a salt is to prevent password attacks with precomputed tables (e.g. rainbow tables), storing the salt along with the hashed password is actually harmless.
Imagine you're a bad guy, and you get access to a password database. There's a lot of information there, things are already bad enough. The only good news for the rest of us is this is dead data in the end. What you really want is access to the living, running system, and the ability to make that system do whatever you want... especially if no one knows you're in.
Here's the trick. To get the access, you don't need to actually discover real passwords: you only need to find some text value that results in the same hash. Worse, you don't need to brute-force a result. There are helpful tables out there that allow you to quickly find texts that will produce the hash you need.
The purpose of the salt, then, is to add a wrinkle against these pre-computed tables. You might have a value that can produce a specific hash, but your pre-computed "rainbow tables" don't account for the salt. A salt completely changes the hash. Now you're back to needing to brute-force individual passwords, and if the system designer used a good encryption algorithm that could take years.
The nice thing here is the salt has this impact even when you know it's value. Just having a per-user salt, even if the salts are public, breaks an attackers ability to use rainbow table attacks on your password database.
(A shared salt, though, would allow an attacker to start running a cracking solution using common passwords, etc and start throwing things against a wall... comparing hash results against all users and see what comes up).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With