The easiest way is to put the salt in front of the password and hash the combined text string. The salt is not an encryption key, so it can be stored in the password database along with the username – it serves merely to prevent two users with the same password getting the same hash.
The salt can and should be stored right next to the salted and hashed password. Additionally, the salt should be unique per password. Its purpose is to make it unfeasible to attack a leaked password database by using precomputed tables of password-hash-pairs.
The best way to store salt is to keep it away from moisture. So, the salt storage container should not permit water or damp in. The container should be able to stay sealed for a long time without contaminating the salt or allowing moisture in.
What is password salting? Password salting is a technique to protect passwords stored in databases by adding a string of 32 or more characters and then hashing them. Salting prevents hackers who breach an enterprise environment from reverse-engineering passwords and stealing them from the database.
The point of rainbow tables is that they're created in advance and distributed en masse to save calculation time for others - it takes just as long to generate rainbow tables on the fly as it would to just crack the password+salt combination directly (since effectively what's being done when generating rainbow tables is pre-running the calculations for brute-forcing the hash), thus the argument that by knowing the salt someone could "generate a rainbow table" is spurious.
There's no real point in storing salts in a separate file as long as they're on a per-user basis - the point of the salt is simply to make it so that one rainbow table can't break every password in the DB.
I will provide a slightly different take on this.
I always store the salt mixed in with the salted-password hash.
For example, I will place the first half of the salt before the salted-hash of the password, and the last half of the salt after the salted-hash of the password. The application is aware of this design so can fetch this data, and obtain the salt and salted-password hash.
My rationale for this approach:
If the password/hash data is compromised and falls into the hands of an attacker, the attacker will not know what the salt is from looking at the data. This way an attacker cannot practically perform a brute-force attack to obtain a password that matches the hash, since he doesn't know the hash to begin with and has no way to know which parts of the data are parts of the salt, or parts of the salted-password hash (unless he does know your application's authentication logic).
If the salted-password hash is stored as-is, then a brute-force attack can be performed to obtain a password that when salted and hashed produces the same data as the salted-password hash.
However, for example, even if the salted-password hash was stored as-is, but pre-pended with a single random byte, as long as the attacker is unaware that this first byte is to be discarded, this would also increase the difficulty of attack. Your application would know to discard the first byte of the data when used to authenticate your user.
The conclusion to this..
1) Never store the data that your authentication application uses in it's exact form.
2) If possible, keep your authentication logic secret for added security.
Go one step further..
If you cannot keep your application's authentication logic secret - lots of people know how your data is stored in the database. And suppose you have decided to store the salted-password hash mixed in together with the salt, with some of the salt prepending the salted-password hash, and the rest of the salt appending it.
When generating the random salt, you could also randomly decide what proportion of your salt you will store before/after the salted-password hash.
For example, you generate a random salt of 512 bytes. You append the salt to your password, and obtain the SHA-512 hash of your salted-password. You also generate a random integer 200. You then store the first 200 bytes of the salt, followed by the salted-password hash, followed by the remainder of the salt.
When authenticating a user's password input, your application will pass over the string, and assume the first 1 byte of the data is the first 1 byte of the salt, followed by the salted-hash. This pass will fail. The application will continue by using the first 2 bytes of the data as the first 2 bytes of the salt, and repeat until a positive result is found after using the first 200 bytes as the first 200 bytes of the salt. If the password is wrong, the application will continue to try all permutations until none are found.
The pros of this approach:
Increased security - even if your authentication logic is known, the exact logic is unknown at compile-time. It is practically impossible to perform a brute-force attack, even with knowledge of the exact logic. Increased lengths of salt will increase security further.
The cons of this approach:
Since the exact logic is inferred at run-time, this approach is very CPU-intensive. The longer the length of the salt, the more CPU-intensive this approach becomes.
Authenticating incorrect passwords will involve the highest CPU cost. This can be counter-productive to legitimate requests, but increases security against attackers.
This approach can be implemented in various ways, and can be made even more secure by using variable-width salts and/or salted-password hashes.
Often, they are prepended to the hash and stored in the same field.
There is no need to store them separately - the point is to use a random salt for each password so that a single rainbow table can't be used against your entire set of password hashes. With random salts, an attacker must brute-force each hash separately (or compute a rainbow table for all possible salts - vastly more work).
If you had a more secure storage location, it would make sense to just store the hashes there.
Based on Developing ASP.NET MVC 4 Web Applications book by William Penberthy:
The point of a salt is to render all rainbow tables useless and require a new set of them to be made. It takes just as long to guess a string as to make a rainbow table.
For example the SHA-256 hash of "password" is 5e88 4898 da28 0471 51d0 e56f 8dc6 2927 7360 3d0d 6aab bdd6 2a11 ef72 1d15 42d8
.
After a salt is added, such as "badpassword" the new string to be hashed is "passwordbadpassword" which, due to the avalanche effect, dramatically changes the output, to 457b f8b5 37f1 802e f9c8 2e46 b8d3 f8b5 721b 7cbb d485 f0bb e523 bfbe 73e6 58d6
.
Normally the salt is just stored in the same database as the password, also because if one database is hacked, it is likely that the other will be, also.
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