A lot of web applications use databases to store user credentials including passwords. Most of these passwords are stored in clear text. While this implementation is easy, it can compromise security. If the application is vulnerable to, for instance, SQL injection attacks, it may be possible for a malicious user to retrieve the entire user list along with their passwords. It may also be possible for anyone with access to the database to access user credentials, depending on how the permission on the database are setup.
One way to avoid exposing passwords is to hash them and store the hash values instead of the original passwords.
Overview of Hashing
A cryptographic hash function, if well designed, will be a one-way operation. This means that there should not be a practical way to obtain an input that will result in a particular hash value. This make the hash value very difficult to predict or forge.
Eg. HashFunction1(InputValue1) = HashedValue1 HashFunction1(InputValue2) = HashedValue2
Even if there is a difference of one character between InputValue1 and InputValue2, the hashedvalues will be significantly different.
Another property of hashing is that for a given input value, using the same hashing function, the same hashed value will be generated. This means that the process is repeatable.
User1 -> HashFunction1(InputValue1) = HashedValue1 User2 -> HashFunction1(InputValue1) = HashedValue1
This property can sometimes be a vulnerability, as we will see in a bit.
Application of Hashing
When a user tries to save a password (while setting or resetting the password), the application computes the hash for that password and saves the hashed value while discarding the original password.
The next time the user tries to login and submits credentials to the application, the hash for the password is calculated and compared against the hashed value stored in the database. If the password is correct, the hashed value in the database should be the same as the hash of the submitted password.
Earlier, I mentioned a vulnerability because the hashing process produces the same hash as long as the same input value and algorithm are used. An attacker could just hash all the values in the password list (dictionary) and try them against the application. For instance, the attacker could get the hashed values using, say MD5 for “password” and try this against the application for a set of user-ids.
To prevent this, a set of characters called ‘salt’ is added to the original values. For instance, the hashed value of ‘password’ will be different from the hashed value of ‘password’+ salt. This means that someone trying to break in with the hashed value for ‘password’ will also have to know the salt value to be successful.
Changes in the Application
Some application functionality may change as a result of using hashed values. For one, applications cannot send users the current passwords in case users forget them. This is actually a good practice and improves security. The other is that, depending on the algorithm used, the size of the hashed values will vary and database column lengths should be adjusted for that.
A few hash algorithms are: Gost-Hash • HAS-160 • HAVAL • MDC-2 • MD2 • MD4 • MD5 • N-Hash • RIPEMD • SHA family • Snefru • Tiger • WHIRLPOOL.
SHA (Secure Hash Algorithm) was designed by the National Security Agency (NSA) and published as a US government standard. Successful attacks on MD5, SHA0 have been reported.