07/06/2011

Password Hashing in Databases

by Cyle
Categories: php
Tags: , , ,
Comments: 1 Comment

Password hashing is vitally important to websites that have usernames, emails, and passwords saved in databases. Since most people use the same password for everything, once the password is obtained a hacker could get access to much more than what is on just your web site. If a hacker gets access to your database somehow, he/she will have a full list of your users, including email addresses and passwords. Probably the same passwords your users use elsewhere. It is extremely important and easy to protect your users’ passwords.

What is a Hash

A hash is also known as hash code, checksum, hash sums, hash values, message digest. A hash is like a fingerprint to the data it represents. A hash is found by mathematical calculations and is virtually impossible to reverse engineer to get the original data. There are many different hashes (md5, Secure Hashing Algorithm 1 (or SHA-1), SHA-2, haval, and many more. They all have different mathematical ways of creating a hash. For the purpose of this tutorial I will be using Secure Hashing Algorithm 2-256. It is more than enough security than you will probably need. To the right is a simplified diagram of the SHA-256 hashing method.

How to Use Hashes

There are many different ways to use hashes, but the method I use most is PHP’s hash() function.

Example:
<?php
echo hash('sha256', 'The quick brown fox jumped over the lazy dog.');
?>
Results in:

68b1282b91de2c054c36629cb8dd447f12f096d3e3c587978dc2248444633483

 
Now lets see a practical example. Below is an example of a registration script that gets the information the user provided (username, password, email, etc) and saves them into the database. We assume the data is being “POSTed” to this page via a form on the previous page, and assuming I am already connected to the database earlier in this page.

User Registration
<?php
/* Store user details */
 
// convert password into hash
$hashPassword = hash('sha256',$_POST['password']);
 
// insert values into database
$sql = 'INSERT INTO Users (username,hashPassword) VALUES (?,?)';
$result = $db->query($sql, array($_POST['username'], $hashPassword));
?>

Now our information is saved in our database, and the next time the user needs to log in we retrieve his hashed password and hash the password he gave at login, and compare the two. If they are the same, we know he entered the right password and will be logged in. Also, in the mean time if a hacker somehow gets a hold of your database, he does not have any passwords, just complicated hashes.

Password Verification
<?php
/* Check user details */
 
// convert entered password to hash
$hashPassword = hash('sha256',$_POST['password']);
 
// search database for username and hash
$sql = 'SELECT username FROM user WHERE username = ? AND hashPassword = ?';
$result = $db->query($sql, array($_POST['username'], $hashPassword));
 
// check to see if any results found
if ($result->numRows() < 1)
{
    /* Access denied */
    echo 'Error: your username or password was incorrect!';
} else {
    /* Log the user in */
    printf('Welcome back %s!', $_POST['username']);
}
?>

 

Is There Any Weaknesses to Hash?

Yes. Hashes cannot be reverse engineered to get the original data, but it can still be compared. Say a hacker got access to your database and now has a list of usernames and their hashed passwords. He cannot figure out a hashed password by reverse engineering, but he can still figure it out. The hacker would have to generate millions to trillions of hashes from his own strings and compare them. If one of his hashes matches the hash he found in your database, then he knows that the string that he used to get that hash is the password. This is called brute forcing. The hacker will generate many possible passwords by arranging letters and numbers or using words (dictionary attack) and hash them to try to match the passwords in your database. Hackers write programs that can do this at rates as fast as a few thousand a second. An 8 character password with at least one uppercase letter and at least one number can take up to 60 hours to brute force match. Hashing only slows the hacker down. Chances are, the hacker could find another website that does not hide the users’ passwords faster than it would take to run a brute force. It is always better to require users to use longer, more sophisticated passwords and hash them for the best security.


1 Comment »

  1. Valmond says:

    > but it can still be compared

    That is why you add a (secret) ‘salt’ to the string before you hash it! Also read up on rainbowtables…

Leave a Reply

Your email address will not be published. Required fields are marked *



user-avatar
Today is Sunday
03/26/2017