Storing passwords securely

User passwords

When writing an authorisation method for your web site it is important to consider the storage of user passwords. Storing passwords in plain text in your database has to be avoided at all costs, as if your application is ever compromised so are the users passwords and these passwords are often used on different sites thus creating a major security headache.

Hashing

A hash is not encryption but a one way computation of data that cannot be reversed, why is hashing important? Because you can store data such as a password without actually exposing what that password is. For example take a look at this PHP code:-


echo md5('test');

The output of the above code is ‘098f6bcd4621d373cade4e832627b4f6’ which represents the value ‘test’. You obviously need to add PHP tags around the above code but if you didn’t know how to do that then this tutorial is not for you.

Okay so you can see how useful a hashing algorithm is useful, but why use it at all? If your database or website is ever compromised the passwords for all the accounts is also broken so you could expose those users to attack (Users often use the same password on multiple sites). If your passwords are hashed this makes the discovery of their passwords more difficult.

I said difficult not impossible

There are collections of password hashes on the internet available to hackers to search or download, they are usually refered to as rainbow tables and it is important that you understand this concept so you completely understand the last code example. A rainbow table works by storing the computed hash in a database or some other form and linking it to the plain text password. So in other words you can search for ‘098f6bcd4621d373cade4e832627b4f6’ and find ‘test’.

Paranoid android

To be a good web programmer you have go to be paranoid, if other developers start calling you paranoid when they look through some of your source code then consider yourself a better programmer than they are. So if you have got what rainbow tables are, then this is how to protect against it even if your users use stupid common passwords.


// Some random characters here, change this!
$seed = '892hSDl3290283';
$password = 'test';
$hashedPassword = md5(md5($password . $seed));

So you take the hashedPassword variable and store this in your users table, to check the password you simply reuse your hash creation method. It would be sense to create a function of this method but I thought I’d keep it simple so that everyone could understand what is going on. This way the users password is never stored in your database only the hashed version. The seed is used to prevent a rainbow table attack on your password because in order for a rainbow tree to be successful it would need ‘test892hSDl3290283’ to be stored in it’s database. The reason that md5 is used twice is because I’m paranoid 😉

2 Responses to “Storing passwords securely”

  1. Alex writes:

    How would you prevent someone from attacking your php code directly. If someone could read what your $seed is, they could do a reverse md5 and find out the password, then login

  2. Gareth Heyes writes:

    @alex

    If they could read your php code then you have bigger problems but you could store the seed in a apache config variable or maybe use a unique seed per user within the table.