As I am writing this post, there happens to be dozens of online tutorials that are still basing their password hashing process on weaker technologies and tools. The widely known one is md5, a reportedly no-longer secure password hashing system available in almost every programming language.

Plain text passwords (no password hashing done)

Some people are lazy and dumb enough to save their inputted passwords as is, into their database as plain text! This is totally bad and horrible! I mean, let’s assume some hacker has gained access to your database (that only means this person can read the data or delete it), as this person lists the users table, they can access raw and plain text passwords and use them to login easily and quickly so as to access more tools and actions limited to admins (saying that as assuming they can’t do nothing hacking into our database except reading raw data). Or even save again a new password and use it later.

Just thinking about it sucks. But if you were to hash your passwords with a strong password hashing system then, they can not revert these passwords, or even if they replace them with plain text, then your password verification will also be negative and keep the bad guys locked out.

md5 is insecure

Yes, if you were hashing your user input passwords with this tool and store into the database users table, that is dangerous and and a bad practice. For its salting and cryptography that is probably static, it is being reverted and reportedly many people have succeeded to do that.

Even though it is insecure, it can be used for hashing strings for minor uses, example when dealing with a quick project that does not require much security. MD5 is used to hash email addresses to get a Gravatar image URL based on the user email, you can test that out.

Using a PHP built-in password hashing system

As if you haven’t heard yet, PHP password_* functions are introduced as of PHP 5 (>= 5.5.0), and available also on PHP’s latest; 7.

The hashing function introduced uses a strong algorithm therefore it’s making it impossible to revert the hash into the plain text password. This is a great security practice to base your project on, especially when creating a social network with PHP where uses are able to register new accounts, reset passwords and so forth.

For earlier PHP versions ( < 5.5 ):

Thanks to ircmaxell’s hard work, you can use password_* functions while you can’t get to PHP 5.5 at least (I know, sometimes to do an upgrade you need to set tight and fix a lot); simple download this package from Github:

https://github.com/ircmaxell/password_compat

And so load the package:

require_once 'password_compat/lib/password.php';

And now you can use those functions and even access useful documentation in the project’s Github page.

Assuming you have the functions in use, let’s carry on with the simple process.

password_hash() function

It is always easy and flexible coding with PHP, from the documentaion you can use:

password_hash( password_from_input_as_plain_text, PASSWORD_DEFAULT )

And here’s an example:

password_hash( 'samuel', PASSWORD_DEFAULT )

Assuming your password field in the form is tagged with the name password:

$password = password_hash( $_POST['password'], PASSWORD_DEFAULT )

Now it is perfect to save into your database users table (wait, saving? let’s not bring that SQL injection talk, be a nice and use PDO’s prepared statements. )

I am just dumping the return of the hash, but it is changing each time even though the plain text password is the same and that is because of the randomly-generated salt used for cryptography.

$2y$10$.HRdBcQBdCSJ0fW60x.MR.v4s6TePvv35p/YxGLlBo0c67n8KcX0.

So let’s say you now feel a little secure, and that you have one more step ahead which is verifying the user inputted password to detect if it matches the one on the database which is hashed, or if not. That’s what you will be using in your login forms, assuming you are at first place searching for a user by its username, email or ID and then move on to verify the password inputted to process and log in this user and then set the PHP session and so..

We’re now taking advantage of PHP’s password_verify() function, which takes 2 parameters one for the plain text and the other for the hash.

Verifying input password with hashed password from the database:

As mentioned earlier, we’re after the boolean returned by password_verify() function. And for it we need to pass the plain text password (as inputted in the form by the user) with the hashed password from the database:

$log_in_verify = password_verify( 'samuel', '$2y$10$.HRdBcQBdCSJ0fW60x.MR.v4s6TePvv35p/YxGLlBo0c67n8KcX0.' )

And $log_in_verify will either return true or false (boolean).

if ( $log_in_verify ) { 
  // Welcome, user!
  // do things in terms of cookie setting and session etc to login this user
} else {
  // You're not welcome, anonymous!
  // alert them that somehow they're not the right guy!
}

Once true, then, don’t worry much and proceed with logging in your user, if it was false then warn the user that they submitted a wrong password, or give them extra more shots and lock them away if they are still insisting to consume your server ressources and bandwidth in order to try silly attempts. Oops, to much aggressive? sometimes you should, especially when you are on a shared hosting and your hosting provided yells at you all the time.

Making a social site that needs more traffic and server ressources? try deploying a VPS on the cloud with Digital Ocean, it’s the most recommended, and I am comfortable with it hosting my applications websites. (Note: referral link for extra bonus)

That’s it!

Yep, feeling like it is. Go out there and make the web a secure place by securing your projects, and sharing secure ways as if you were to help someone with their own project.

Digital Ocean

Cheap Cloud SSD Hosting

Get a VPS now starting at $5/m, fast and perfect for WordPress and PHP applications

Sign Up with $10 Credit