One task that often arises in programming is how to securely save the password entered by users.
There are at least two types of password that need to be saved. The first one is a password that is intended to be used as user authentication such as a login to a website. The second one is a password that will be used to access other service. An example for this type is your password in email client program that will be sent to email server to access your account.
For security reason, a password is usually not saved in plain text format but in different form. One of the forms is its hash value. There are many methods available to calculate the hash value such as MD5, SHA-1, Blowfish, etc. Selection of the method to calculate hash value depends on the application. For password that intended for user authentication, a one-way hash function such as MD5 or SHA-1 is usually used. For password that will be used to access other service, the password needs to be recoverable so the hashing algorithm should be able to get the original password. Blowfish or AES is usually used for the second application.
Saving a password in its hash value is not really secure. For example, suppose that we will use the MD5 hash function to save the hash of the password mypassword. The following PHP code can be used to get the hash value of this password.
$hash = md5('mypassword'); echo $hash;
This will give you the hash:
34819d7beeabb9260a5c854bc85b3e44
Now, if we save this hash value to authentic user, and if someone can read this value, that person theoretically will be able to guess the original password, either by using dictionary attack or brute force. What this person needs to do is find a word that has MD5 value as the one saved.
To avoid this problem, usually the hash value is combined with other information such as login name. For example, instead of saving the hash of mypassword, we can prepend it with two first characters of the login name and append it with the rest of the login name. The idea is to make it difficult to guess in case someone able to read the saved value.
There are many methods that you can use to combine the password so that we can avoid saving the hash in the original password form, such as illustrated in the following code fragment.
$password = 'mypassword'; $username = 'mylogin'; $crc = sprintf('%u', crc32($username)); $pass = substr($password, 0, 2); $pass .= $crc.substr($password, 2); $md5 = md5($pass); $hash = substr($crc, 0, 2).$md5.substr($crc, 2); echo "<p>CRC: $crc</p>"; echo "<p>Pass: $pass</p>"; echo "<p>MD5: $md5</p>"; echo "<p>Hash: $hash</p>";
Which will give you:
CRC: 923439711 Pass: my923439711password MD5: 0dbf15baa305031732efcdb8fe42135c Hash: 920dbf15baa305031732efcdb8fe42135c3439711
Now if we save the last hash value, it will be more difficult to guess. For one, the length of the saved hash value is longer than the MD5 value.
For second application, we need to be more careful because the password needs to be recoverable, so whatever method we use to obscure the password, it needs to be reversible.
Note: MD5 has been shown not collision resistant, meaning multiple values can produce the same hash value. You can use different hash function like SHA-512 to get more secure system. The following code fragment shows how the SHA-512hash value can be calculated in PHP.
$hash = hash('sha512', 'mypassword'); echo $hash;
Which will give you the has value:
a336f671080fbf4f2a230f313560ddf0 d0c12dfcf1741e49e8722a234673037d c493caa8d291d8025f71089d63cea809 cc8ae53e5b17054806837dbe4099c4ca
Get more information by using Google search