OWASP Series - Insecure Cryptographic Storage
Do you recognize this?
5F4DCC3B5AA765D61D8327DEB882CF99
It is the MD5 hash for 'password'. Even if you hash important data in your database like passwords does not mean someone else can't recognize it, even by sight. Most hackers or security specialists will recognize this hash and many others without a problem as if they were stored in cleared text.
Many know that you can't directly decrypt a hashed string. That is true, but that does not mean it is secure.
For example, let us say that we have a hashed string where we want to find the original value. We suspect the original string was alphanumeric without any special characters and that it was 6 characters in length or less*. We can create a database table and then roll through all the possible strings going from 1 to 6 characters and store the string and its hashed version. Then it is just a simple SQL call to match the hash with one in the database and then pull the string that generated it. Hash dictionaries can even be downloaded off the Internet, saving the time of having to generate one. So even with this strong encryption pattern, we are not safe.
Now we have some things to consider here. Hashing is not enough, but we can 'salt' the hash. We take the original string and add a random 'salt' of characters to it, and then we hash the combined string. Salting the hash will buy us more time. A hacker can't use a brute-force attack against the hash within an acceptable timeframe with a proper salt. But remember Moore's law and realize that processing power is always growing. Make sure your salt is indeed random and in a good length (like 32 bits) to make it effective.
Wikipedia has a good explanation salts at..
http://en.wikipedia.org/wiki/Salt_(cryptography)
So remember, "salted hash".
To further illustrate the setup of this, imagine a situation where we have a database table of username and passwords. With a random salted hash pattern, we actually would have three critical columns in our table: username, password (hashed), and the random salt. If we need to verify the user's password, we take the password string and combine it with the random salt from that row and then execute the hash function. Then we see if that hashed value matches the one in the table. If it does, all is good and we log the user into the application.
By the way, if you have a password reminder function in your application, a hash will make the functionality of it unless. If someone needs a password reset, do some proper proof of identity and generate a random password and send it to them. When they login, force them to make a new password which you naturally hash with a random salt and store.
* Determining the patterns are fairly simple. Most passwords are simple one word or date patterns 6 characters or less. Social security numbers are 11 integers long with the dashes. It's 9 without. You get the idea.