Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hashing Password, from broken methods to most secure now

I have just simple question in my mind for community . Once upon a time when i started programming i used md5 for hashing password, than later found that md5 can be cracked easily and i should use salt to make it secure.

Than i had no faith in md5 and wanted to use sha1,sha256,sha512 encryption. But the problem is now i have passwords in encrypted form which is

md5("password"+"salt")

At that point i didn't knew the password of users.So what i did

sha1(md5("password"+"salt"))

Now after few time in this field i found sha1 is also not too secure and is broken what should i do is use bcrypt() to make password secure .

so from now i will be using

 crypt(sha1(md5("password"+"salt")))

Password is now very secure but the main problem still is about the time it will use to create hash value will always be greater than to use bcrypt("password")

Now what i want to say suppose if bcrypt is hacked and is found to be broken and in future there comes new cryptographic function that is more secure and. Than this way creating a password from old values will always be time consuming.

What could be the solution for this. as i know mailing users to change password is not always 100% successful. Another thing is to add a new field in database that store new hashed values and if all the fields are filled than remove the md5 values from db .But thing in this way previous hashed values are still visible.

So will this thing be going on, or you guys have some solution. :)

like image 331
Abhishek Avatar asked Apr 10 '13 18:04

Abhishek


1 Answers

PHP 5.5 introduces the Password API which addresses this issue:

The new Secure Password Hashing API in PHP 5.5

The RFC for a new simple to use password hashing API has just been accepted for PHP 5.5. As the RFC itself is rather technical and most of the sample codes are something you should not use, I want to give a very quick overview of the new API:

Why do we need a new API?

Everybody knows that you should be hashing their passwords using bcrypt, but still a surprising number of developers uses insecure md5 or sha1 hashes (just look at the recent password leaks). One of the reasons for this is that the crypt() API is ridiculously hard to use and very prone to programming mistakes.

By adding a new, very simple to use API we hope to move more developers towards bcrypt.

How to hash passwords

Creating password hashes can't be any simpler than this:

  $hash = password_hash($password, PASSWORD_DEFAULT);

This will create a password hash using the default algorithm (currently bcrypt), the default load factor (currently 10) and an automatically generated salt. The used algorithm and salt will also be part of the resulting hash, so you don't need to worry about them at all ;)

If you don't want to stick with the defaults (which might change in the future), you can also provide algorithm and load factor yourself:

$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);

Verifying passwords

Verifying passwords is just as easy:

<?php
// $password from user, $hash from database
if (password_verify($password, $hash)) {
    // password valid!
} else {
    // wrong password :(
}

Remember: The salt and algorithm are part of the hash, so you don't need to provide them separately.

Rehashing passwords

As time goes by you might want to change the password hashing algorithm or load factor, or PHP may change the defaults to be more secure. In this case new accounts should be created using the new options and existing passwords rehashed on login (you can do this only on login because you need the original password to do a rehash).

Doing this is also very simple:

<?php
function password_verify_with_rehash($password, $hash) {
    if (!password_verify($password, $hash)) {
        return false;
    }

    if (password_needs_rehash($hash, PASSWORD_DEFAULT)) {
        $hash = password_hash($password, PASSWORD_DEFAULT);

        // update hash in database
    }

    return true;
}

The above snippet will keep your hashes up to date with the PHP default. But once again you can also specify custom options, e.g. password_needs_rehash($hash, PASSWORD_BCRYPT, ['cost' => 12']).

Compatibility layer for older PHP versions

The new API will only be introduced in PHP 5.5, but you can already use a PHP implementation of the same API now! The compatibility implementation will automatically disable itself once you upgrade to 5.5.

like image 92
John Conde Avatar answered Oct 31 '22 15:10

John Conde