Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel & Meteor password hashing

I have two applications, one in Laravel 5.2 and one in Meteor. I want to collect hashes for passwords which are compatible with both platforms.

The database stores the hashes separately

  • password for Laravel.
  • meteor_password for Meteor.

Both platforms use bcrypt with 10 rounds by default, but Meteor appears to sha256 the plain password before bcrypt.

If Meteor creates password hash abc, I can sha256 the plain password, and compare it with abc using Laravel's internals, i.e. Auth::attempt()

$sha256 = hash('sha256', $request->get('password'), false);

This works. Laravel successfully authenticates the user.

However, if I register a new user in Laravel, and store the hash meteor_password, when authenticating against that hash in Meteor, it fails with the error message "Login Forbidden". This error appears to be mean incorrect credentials.

I'm creating the hash in the same way as I did when I verified it in Laravel.

$meteor_password = bcrypt(hash('sha256', $plain, false));

It seems strange that it'd work one way and not the other so I assume I'm missing something.

like image 943
Ben Swinburne Avatar asked Sep 26 '22 11:09

Ben Swinburne


1 Answers

In 2011, a bug was discovered in PHP's BCrypt implementation, so they changed the original 2a version indicator to 2x and 2y, which is used today, to indicate that the password was hashed by the fixed version.

Therefore, the hash generated by PHP's 2y should be identical to the one generated by node's 2a.

The prefix should be changed in order to be correctly processed by the NPM module (used by Meteor), as it does not acknowledge 2y.

$meteor_password = bcrypt(hash('sha256', $plain, false));
// replace it useing something like:
$meteor_password = str_replace('$2y', '$2a', $meteor_password);
// or
$meteor_password[2] = 'a';
like image 164
MasterAM Avatar answered Sep 29 '22 05:09

MasterAM