Up until recently I was using md5 to secure encrypt my passwords before passing them to the database. This was pretty sloppy on my part and came about as when I learnt to encrypt passwords, a lot of people seemed to be using md5 or sha1 ( according to the blogs I read ). I then ticked off that box in my development tools and went on my merry way to learn fun stuff.
Recently when building a new site I thought I would revisit password encryption, and realised I had a bit of work to do…
What’s a Hash
No, we aren’t smoking here. To keep with the web developing cats philosophy of taking everything from basics, lets have a quick look at what a password hash is.
To quote the Wikipedia entry directly, “A cryptographic hash function is a hash function; that is, an algorithm that takes an arbitrary block of data and returns a fixed-size bit string”. In layman’s terms, a hash takes your password and applies an algorithm giving you what appears to be a meaningless string at the other end; hopefully cloaking the original password in an uncrackable form. A cryptographic sausage machine, if you will, where the password is the ingredients, and the hash is the sausage…
Popular Hash Methods
I find the majority of tutorials in the PHP world for beginners point users towards using an md5 hash, or for the slightly more progressive, a sha-1 hash. Up until a few weeks ago I would have done the same. Either of these hashes are easy to use and implement. Get your password from the registration form, and pass it through an md5 call. Et voila, you have a hashed password.
$password = $_POST[ 'password' ]; $hash = md5( $password );
Nice and simple, eh? Except I’m beginning to believe that using md5 isn’t that secure. I’m no expert, but I’ve read enough blogs and tutorials from trusted sources to conclude I should be using more solid methods of securing passwords. After all, people are entering their data on my sites assuming it will be kept safe, so as web developers we have a duty to so this. And if you need any persuading, the php manual tells it straight. That’s good enough for me.
Enter Phpass, a class that will encrypt your passwords using encryption methods well beyond my ken. The developer of phpass gets into the dirty details of his phpass class and general encryption here, if you want a fuller explanation. For my part in this post, I will show you how to simply integrate phpass into your site, use it to create a secure hash as would be done on a site registration, and then how to check a password as would be done in a login function.
To start with, download the class from here – Phpass 0.3 Download. Once you get the archive file, unpack it and look for PasswordHash.php. Store this file in your project, somewhere you know the path to.
To include the class in your script, we include it like any other php file:
include ( '/path/to/PasswordHash.php' );
Creating Our Hash
NB: I’m not going to go into detail on how to create a registration function, as I have done so already here. The code I am going to show you is solely on how to encrypt your password. This code would be done in-between after getting the password as entered by the user on your registration form, and before writing the password to the database.
Back to the code. The first thing we need to do is instantiate a new object of the PasswordHash class.
$password = $_POST[ 'password' ]; $hash_obj = new PasswordHash( 8, false );
What are those parameters, ‘8’ and ‘false’, that we are passing? The first relates to a technique called ‘password stretching’, and the second relates to ‘Portable hashing’. I don’t know enough about these to explain well, so again I will point you to the developers site for a full explanation.
Now we put pass our password through the following function to create our new hash:
$hash = $hash_obj->HashPassword( $password );
We now have a hash. But just in case anything has gone wrong, we will do a quick check on the length of the hash string. Due to the nature of the hash method being used, the shortest hash we can possibly get is twenty chars long. So if we get less than that, something has gone amiss.
if ( strlen( $hash ) < 20 ) return false;
Otherwise, we can now safely store the hash in our database, for example,
$db_obj->insert_password( $hash ).
Checking our Hash
The reverse operation is checking an entered password against a hash we have stored in a database, and is usually employed during a login process. With phpass, this is all very easy. ( I will be using psuedo code to represent the database operations needed to get the applicable data )
Typically a user will enter a username and password when trying to login. From their username, we get the stored hash from the database
$username = $_POST[ 'username' ]; $stored_hash = //get stored hash from database where username = $username_entered
We then take the password they entered and using phpass, check it against our stored hash:
$password = $_POST[ 'password' ]; $check = $hash_obj->CheckPassword( $password, $stored_pass );
The method will return true if there is a successful match, and false if not:
if ( $check ) return true return false;
Safe as Houses.
Well, probably not, but a lot more secure than securing your passwords with md5 or sha-1. The phpass site will give you some impressive numbers as to why using phpass is safer. And anway, as this post has shown, it’s no trouble at all to implement this method on your sites, so you might as well :)
That’s all for now, but if you would like to be kept up to date with new posts here at the web developing cat, then be sure to add your name to our mailing list below.