Thursday 26 September 2013

Password Hashing In PHP

Most modern PHP applications access important user information and store them in a database. For example, web app might have a registration system for new users. But how should you store usernames and passwords in the database?
You must always think about security. If passwords are stored in plain text, what happens if an attacker gains access to your database? He can easily read all of the users’ passwords. That’s why we use a technique called password hashing to prevent attackers from getting user passwords.
In this article you’ll learn how to store the passwords securely in the database so that, even if your database falls into wrong hands, no damage will be done.

What Is Password Hashing

Hashing is not a new concept. It has been in practical use for quite a long time. To understand hashing, think about fingerprints. Every person has a unique fingerprint. Similarly, each string can have a unique fixed-size “digital fingerprint” called a hash. For a good hashing algorithm, it’s very rare that two different strings will have same hash (called a collision).
The most important feature of hashes is that the hash generation process is one way. The one way property indicates that it’s impossible to recover the original text from its hash. Therefore password hashing perfectly suits our need for secure password storage. Instead of storing a password in plain text, we can hash the password and store the resulting hash. If an attacker later gains access to the database, he can’t recover original password from the hash.
But what about authentication? You can no longer compare the password entered by user in a login form with the hash stored in the database. You need to hash the login password and compare the result with the hash stored in the database.

How Hashing Is Done In PHP

There are different algorithms for generating hash of a text. The most popular ones are: MD5, SHA1, and Bcrypt. Each of these algorithms are supported in PHP. You really should be using Bcrypt, but I’ll present the other alternatives first because they help illustrate what you need to do to protect your passwords.
Let’s start with PHP’s md5() function which can hash passwords according to the MD5 hashing algorithm. The following example demonstrates the registration process:
<?php
$username = $_POST["username"];
$password = $_POST["password"];
 
// create connection to database
 
// create an MD5 hash of the password
$password = md5($password);
 
// save the values to the database
$sql = "INSERT INTO users (username, password) VALUES (:username, :password)";
 
$stmt = $db->prepare($sql);
 
$stmt->execute(array(
    ":username" => $username,
    ":password" => $password
));

And the following example shows the authentication process:
<?php
$username = $_POST["username"];
$password = $_POST["password"];
 
// create connection to database
// ...
 
// create an MD5 hash of the password
$password = md5($password);
 
// retrieve the information from the database
$sql = "SELECT * FROM users WHERE username=:username AND password=:password";
$stmt = $db->prepare($sql);
$stmt->execute(array(
    ":username" => $username,
    ":password" => $password
));
 
$row = $stmt->fetch();
In the above example, md5() creates a 128-bit hash out of the given password. It’s also possible to use sha1()instead of md5() which produces a 160-bit hash (which means there’s less chance of a collision).
If you generate an MD5 hash of the string “MySecretPassword” and output it to the browser, it will look like the following:
7315a012ecad1059a3634f8be1347846