I promised that once we learned more about password cracking we would come back to salts.
If you remember, I mentioned that one of the ways salts made passwords harder to crack was by making them longer. As you’ve learned, every additional character exponentially increases the amount of possible character combinations. Once the hacker finds out what the salt is, this is no longer the case. The attacker can edit any dictionary or brute force password cracker code to add the salt to the current word before running it through the hash function. The attacker can now run normal password lists and brute force attacks as if the salt wasn’t even there. This can also applied on a larger scale. If the attacker found out that the salt was the user’s username, he could easily automate a password cracker by editing the code to attach the user’s username to the password. So as you can see, it is important to create good salts and store them as securely as possible.
Random Salts vs. Unique Salts
So which is better, having random generated salts, or unique salts like your username or email address? It depends on how you store it. If it is in the same database as your username and password hash, then it doesn’t matter if it’s random or unique, because it’s being stored either way. Once the hacker gets access to the database and dumps the username/password database, to figure out what the salt it he would need to try every stored value (username, email, name, etc..) until he cracked the password. He would then know what the salt was for every other user. The attacker could also just choose to try and crack the password hash as is, and if successful he would see the salt and password in plaintext. The attacker would then compare the plaintext with the database values under that user and see where it matches up, finding the salt. This would probably take much longer or wouldn’t work depending on how long the salt and password combination is.
This would be a different situation if the salt was stored in a different server because if the attacker had access to one database, he might not have access to the other. In this case, using a random salt would make sense because the attacker would still be able to guess a unique salt like a username, but not a random hash stored elsewhere.
For even greater security, in addition to using a salt that is stored in the database, you could add to it in the actual source code of the register/login script. This way, the attacker would need to have access to both the database and the source code to be able to get the salt.