Reason for salting password hash (or, why “season” the password?)

I recently decide to start re-learning PHP, and started with building in a security framework for the application I’m developing. In my search for how to implement password authentication in PHP, I started to notice that many still neglect “salting” the password at rest. In other words, many believe that creating an MD5 hash of the password is enough. This is simply not the case. The whole reason for salting a password is to create randomness in the password hashes created.

The idea behind a hash, or checksum, is to create a consistent way to verify that data was not altered. Hashing has expanded into a way of creating a way to store a non clear-text password. In other words, a hash is not encryption, but a mathematical way of representing the data’s state at the time the hash was created. A hash is not something to be decrypted, but used as a comparison between the stored password (password at rest) and the password provided for comparison (i.e. the password provided by the end user when logging into the system). Many start using a hash with the idea of “decrypting” the password, when the hash is really used for comparison.

In order for the hash to be of any value, it must always be calculated the same way and return the same value representing the data’s state. So, if a file was created ten years ago, nothing has changed with the file, the hash value of the file will be today what it was ten years ago. The same applies to a password. If my password today is ‘foo’, and I never change it (shame on me), the hash value of ‘foo’ will be the same ten years from now.

Now here’s the problem with not salting passwords. Because the hash reliably and consistently returns the same value for unaltered data, if two (or more) people decide to use the password ‘foo’, the hash value for both people’s password will be identical. On the surface, this seems like what we want – a consistent way of representing the data. The problem is when the password source (ex. password file, database table where passwords are stored, LDAP directory, etc.) is compromised. An attacker now has a way of determining one or more passwords for the system.

For the sake of discussion, below is a list of possible passwords and their hashes (using the SHA256 algorithm) and a list of passwords obtained from a system:

Possible passwords:


bar,d82c4eb5261cb9c8aa9855edd67d1bd10482f41529858d925094d173fa662aa91ff39bc5b188615273484021dfb16fd8284cf684ccf0fc795be3aa2fc1e6c181
foo,f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7
password,b109f3bbbc244eb82441917ed06d618b9008dd09b3befd1b5e07394c706a8bb980b1d7785e5976ec049b46df5f1326af5a2ea6d103fd07c95385ffab0cacbc86

Current system passwords:

jim,d82c4eb5261cb9c8aa9855edd67d1bd10482f41529858d925094d173fa662aa91ff39bc5b188615273484021dfb16fd8284cf684ccf0fc795be3aa2fc1e6c181
john,f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7
bob,b109f3bbbc244eb82441917ed06d618b9008dd09b3befd1b5e07394c706a8bb980b1d7785e5976ec049b46df5f1326af5a2ea6d103fd07c95385ffab0cacbc86
alice,b109f3bbbc244eb82441917ed06d618b9008dd09b3befd1b5e07394c706a8bb980b1d7785e5976ec049b46df5f1326af5a2ea6d103fd07c95385ffab0cacbc86


As you can see, a pattern emerges. Several end users have the same password hash, and the password is … ‘password’ for the end users in question. This shows us that no password salting is occurring, and comparison of possible passwords with end user passwords will yield the clear-text password used by the end user. For example, jim is using the clear-text password of ‘bar’, and john is using the clear-text password of ‘foo’.

Now, let’s salt the passwords and see what happens:

Possible passwords:


bar,d82c4eb5261cb9c8aa9855edd67d1bd10482f41529858d925094d173fa662aa91ff39bc5b188615273484021dfb16fd8284cf684ccf0fc795be3aa2fc1e6c181
foo,f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7
password,b109f3bbbc244eb82441917ed06d618b9008dd09b3befd1b5e07394c706a8bb980b1d7785e5976ec049b46df5f1326af5a2ea6d103fd07c95385ffab0cacbc86

Current system passwords:

jim,187ff9a18d6bf7a355638e7bd44322c6434b7f4893138b2ee6e15fec942e7064b2c20032f61f5b8ac6031c26e1ced675caea0b25daf5c866c57171ea3aa5e3b5
john,62cca9737dea4ee4491e1713228e7e0e9eddb3c6d7d8dfe69a91192336b90e4cbe75f86749d101b8e86789f46a90358c0090c13851da3bf26d6ee145374db488
bob,09f3a485fa3ef069ce2d0af74b20a3029a01d5a5ddd37d1f2aa8e9a566f9fffa55e2eeed69b5f7bfffe6a3bd3fe09a3e0bb064bd6380d61055ea29fb713501ef
alice,263b31fab3f325cdb9a550467b5b8014829bc218ed9e464a65321dc7054d0a86ec95a413b5cc805864530e3c700fdf9ccdefad17499afc8a386be035e6066c16


The pattern we saw earlier is no longer evident. In fact, even knowing the salt used in hashing the password is of no help, because the salt is different for each password generated. The end users with ‘password’ show different hashes, because different salts were used to generate the hashes. If we did not know from the earlier example that the end users used the same password, we would have no idea they were the same. This is why a salt is used – to generate randomness in generating hashes.

In summary, first assume that the place where passwords are stored will be compromised. The idea is that we need to slow down the progress of the attacker. Adding randomness to passwords is one way to slow down the attackers’ progress. In the end, depending upon the time and resources available to an attacker, and how valuable the information is being protected, the attacker will find a way to discovering clear-text passwords from generated hashes, even with a salt applied. The goal in information security is not about 100% protection, but reduction of risk. The risk of discovering clear-text passwords from unsalted hashes is greater than discovering clear-text passwords from salted hashes.