Encrypting Passwords in a Database

by ShiverCube on Dec.18, 2009, under PHP

I was astounded after reading an article to find out that 30% of websites store passwords as plain text in a database. It is a fairly straightforward task to encrypt a password before storing, but provides a lot of extra protection to the confidential private data which is stored within your database.

However, you should only store confidential user information if absolutely necessary. If all you require is simple site login authentication for user identification, then consider using another existing secure service such as Facebook, Google, OpenID or OAuth. If possible, these services should be used instead of creating your own authentication system.

If you require your own user system, passwords should be stored in a database as a hashed value with a salt. This is demonstrated clearly in Elliot Haughin’s Handling Passwords In CodeIgniter post. These same principles can be applied to any type of PHP code.

Just using a hashed value is an inadequate form of security. Currently SHA1 is simplest and best hash function to use. MD5 should not be used instead of SHA1, as it is less secure.

A salt should be stored within a hidden file somewhere on the server, not in the database itself. It should be appended onto the hash of a password. An example salt could be like the following.

/**
 * The encryption salt value. This should be a 32 character long string of lowercase, uppercase, number
 * and optionally symbol characters
 */
$config['encryption_key'] = 'aB8Lc7McI7tnp.*o6LvZiW(@zVBHaxmx';

To encrypt the password, a function such as the following could be used.

/**
 * Encrypts a given password using a one way encryption technique
 *
 * @param $password string The password to encrypt
 * @pre $password is non empty
 * @return string The encrpyted password
 */
function encrypt_password($password)
{
	return sha1($password) . $config['encryption_key'];
}

Upon user registration, instead of storing the plain text password, the encrypted password should be used.

/**
 * Adds a new user to the database
 *
 * @param $data object The object containing the user information to register
 * @pre $data->username is a non empty unique sanitized string
 * @pre $data->password is a non empty string
 */
function register_user($data)
{
	$password = encrypt_password($data->password);
	execute_query("
		INSERT INTO users ('username', 'password')
		VALUES ('{$data->username}', '{$password}');");
}

Then to verify login, just re-encrypt the password and compare it with the value stored in the database.

/**
 * Determines whether a user is authenticated
 *
 * @param $username string The user specified username
 * @param $password string The user specified password
 * @pre $username is non empty sanitized string
 * @pre $password is non empty
 * @return bool TRUE if the user is authenticated; otherwise false
 */
function login($username, $password)
{
	$password = encrypt_password($password);
	return execute_query("
		SELECT username FROM users
		WHERE 'username' = '{$username}'
		AND 'password' = {$password};")->num_rows() == 1;
}

This provides a simple, yet secure, mechanism for storing passwords within your database.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
:PHP, Programming, Security

No comments yet. Feel free to voice your opinion.

Your thoughts are welcome

Search

Use the form below to search the site:

Still can't find what you're looking for? Comment on a post or contact me so that I can try and help you in any way that I can.

Archives

All entries, chronologically...