Framework: [5.7] Mixing hashing algorithms not working

Created on 5 Sep 2018  路  3Comments  路  Source: laravel/framework

  • Laravel Version: 5.7.1
  • PHP Version: 7.2.5
  • Database Driver & Version: MySQL @ 5.7.23

Description:

The RuntimeException thrown in illuminate/hashing/ArgonHasher.php, check method, breaks backwards compatibility when mixing hashing algorithms.

Currently trying to migrate hashes from bcrypt to Argon2. We rehash passwords after authentication and are running into issues when trying to even login with a bcrypt hash. RuntimeException on line 1 of snippet.

if ($this->attemptLogin($request)) {
    $user = Auth::user();
    if (Hash::needsRehash($user->password)) {
        $user->password = Hash::make($request->input('password'));
        $user->save();
    }
}

Steps To Reproduce:

  1. Have existing users with bcrypt hashes
  2. Use Argon as hashing driver
  3. Login as user with a bcrypt hash

Notes:

Removing throw from ArgonHasher returns to working as expected

Most helpful comment

I am also having issues with the algorithm checking not quite working as intended.

The hashes I have have been generated over time with different versions of bcrypt and portions have stopped working with Laravel 5.7.

See https://en.wikipedia.org/wiki/Bcrypt#Versioning_history - Bcrypt has had several versions over the years, with the latest identified by the $2y$ prefix.

Now, for whatever reason PHP's password_get_info() function _only_ recognises https://github.com/php/php-src/blob/master/ext/standard/password.c#L81 the $2y$ prefix despite the fact that there are other versions.

Since, behind the scenes $this->info is 'password_get_info()' Laravel now rejects valid bycrpt hashes that don't have $2y$ prefixed. https://github.com/laravel/framework/blob/5.7/src/Illuminate/Hashing/BcryptHasher.php#L60

Example

$hash = '$2a$10$Wrk/FoakWwkX/tT0A/No5uu3IZrVu/e27QHTgpjHlPUQS3HwK0ei2';
password_verify('Test12345', $hash); // bool(true) 
password_get_info($hash); // array(3) { ["algo"]=> int(0) ["algoName"]=> string(7) "unknown" ["options"]=> array(0) { } }

I'll make a pull with a fix...

All 3 comments

I am also having issues with the algorithm checking not quite working as intended.

The hashes I have have been generated over time with different versions of bcrypt and portions have stopped working with Laravel 5.7.

See https://en.wikipedia.org/wiki/Bcrypt#Versioning_history - Bcrypt has had several versions over the years, with the latest identified by the $2y$ prefix.

Now, for whatever reason PHP's password_get_info() function _only_ recognises https://github.com/php/php-src/blob/master/ext/standard/password.c#L81 the $2y$ prefix despite the fact that there are other versions.

Since, behind the scenes $this->info is 'password_get_info()' Laravel now rejects valid bycrpt hashes that don't have $2y$ prefixed. https://github.com/laravel/framework/blob/5.7/src/Illuminate/Hashing/BcryptHasher.php#L60

Example

$hash = '$2a$10$Wrk/FoakWwkX/tT0A/No5uu3IZrVu/e27QHTgpjHlPUQS3HwK0ei2';
password_verify('Test12345', $hash); // bool(true) 
password_get_info($hash); // array(3) { ["algo"]=> int(0) ["algoName"]=> string(7) "unknown" ["options"]=> array(0) { } }

I'll make a pull with a fix...

Duplicate of #25586

This has been fixed in 5.7.4

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghost picture ghost  路  3Comments

JamborJan picture JamborJan  路  3Comments

progmars picture progmars  路  3Comments

SachinAgarwal1337 picture SachinAgarwal1337  路  3Comments

CupOfTea696 picture CupOfTea696  路  3Comments