Security and privacy became the number one words when talking about internet nowadays. And knowing how to build applications that can keep your customers’ data safe is crucial.

In this article we are going to see the  best practices of persisting users’ passwords in PHP.

Crackers

Since the very first line of code was written down developers have been dealing with crackers. The nature of web makes softwares and websites even more susceptible to attacks.

Cases keep popping up all the time. And if big companies like Twitter, Linkedin, Gmail have troubles all the time leave alone another business.

Ways to protected your data

Having in mind that our websites will be attacked in some stage. Developers have tried by all means to avoid data loss.  At the very begin the use to save row password:
<?php
...
$password = '123456';
.
echo $password;

Quickly they found out it was not a very good way to keep this type of information. They started using a few cryptography methods such as MD5 , SHA1:

<?php
...
$password = sha1( '123456' );
.
echo $password;
# output: 7c4a8d09ca3762af61e59520943dc26494f8941b

It seemed like a good solution. However, didn’t take long to find websites with charts of decrypted passwords (here an example), bringing us  back to square one.

Adding some salt

Alright, encrypting flat password strings wasn’t good enough. That’s when someone had the idea of adding an ‘extra’ into the passwords before processing it. This technic is called Salt and basically works like below:

<?php
...
$salt = 'Some_custom_string';
$password = sha1( '123456' . $salt );
.
echo $password;
# output:   a7e8ab4a815db488122d5f7e849fa64a3258c450

Cool, our problems were finally sorted. Not quite yet. If we think about an attack where the crackers got far enough to have access to our database, it’s very likely they also got into the application code base. Therefore, the salt code.

Hashing things

Another way to try to keep your data save is using the PHP function hash. This function, added to php 5, works with many different types of cryptography.  On the case below I’m using sha256:

<?php
...
$salt = 'Some_custom_string';
$password = hash( 'sha256',  '123456' . $salt );
.
echo $password
# output:   c79ba758bfd9a70ff3a5a148f69a119f2011133e52a7ead7b616e97351240775

At the moment I’m writing this article sha256 and sha512 haven’t been broken yet. Although, it can happen in the future once machines and crackers are getting day after day even more sophisticated.

Also, using multiple hashes combined does not make your algorithm safer. Hashing once, using the best (with more bits) algorithm and adding salt does.

What are Zend and the community doing about that?

php

On the version 5.5 of PHP was created an API to handle passwords. It provides a professional and safe way to work with password in our applications. Take a look below:

<?php
...
$password = '123456';
$password = password_hash( $password, PASSWORD_DEFAULT );
.
echo $password;
# output:   $2y$10$dYKos9pDyz2DVTDXht.SFew6SjWC9KGwqw2lUs3cmlFJ2lTVhbVDS

You can notice that this time was generated a 60 characters output. PHP used Bcript, which is one of the safest algorithm around these days.

Keys generated with Bcript always start at the same way $2y$1

PHP password_hash function is flexible enough to give you the ability to change the salt it uses:

<?php
.
$password = '123456';
.
$options = [
'salt' => 'Some_custom_string_again' // it has to be greater than 22 characters
'cost' => 10,
];
.
$password_with_hash = password_hash( $password, PASSWORD_DEFAULT, $options );
.
echo $password_with_hash;
# output:   a7e8ab4a815db488122d5f7e849fa64a3258c450
.
// verifying the password
var_dump( password_verify( $password , $password_with_hash ) );
# output: bool(true)

Keep in my that Bcrypt is really heavy when comes to performance in your server. Asking our hardware for a lot of processing to generate the passwords.

The recommended value for cost is 10 (either add the option ‘cost’ => 10 into your array $options or nothing, once 10 is the default) to still have safe password and keep your server in a health state.

Keep safe and carry on

In the end of the day, keep your application and users’ data safe is a matter of good habits in both sides: application and user. On the first case, add layers of protection as we mentioned above: hashing, salt, firewalls, updated hosting servers, latest version of the languages and so forth.

In the second case, just consider to force your user type safer passwords:

  1. They must have at least 8 characters in their password;
  2. Each of those 8 characters should mix letters (upper or lower case), a number, a special character.  Which means at least something like 75 possibilities for each position;

There are many other approaches that can take place to make your application safer. Those ones above are just one layer out of many implementations.

Happy coding!

References

http://www.pctools.com/security-news/crackers-and-hackers/
http://www.dailymail.co.uk/news/article-2272315/Twitter-hackers-Quarter-million-users-personal-data-stolen.html
http://money.cnn.com/2012/06/06/technology/linkedin-password-hack/
http://sanfrancisco.cbslocal.com/2012/06/07/google-alerts-gmail-users-of-possible-hacker-attack/
http://en.wikipedia.org/wiki/Data_loss
http://en.wikipedia.org/wiki/Cryptography
http://en.wikipedia.org/wiki/Salt_%28cryptography%29
http://us2.php.net/manual/en/function.hash.php
http://en.wikipedia.org/wiki/Bcrypt