How to compare a bcrypt hash between PHP and Node.js

How to compare a bcrypt hash between PHP and Node.js
Table of Contents

I'm in a situation where a Node app and a PHP app are sharing a database. The PHP app handles the user registration and hashes the password using password_hash().

The password_hash() function uses the bcrypt algorithm if you specify PASSWORD_DEFAULT or PASSWORD_BCRYPT.

With Node, the bcrypt NPM module can be used to compare the hash and the plain password, with a little gotcha.

There are multiple versions of bcrypt: https://en.wikipedia.org/wiki/Bcrypt#Versioning_history

PHP uses $2y$ while this NPM module uses $2a$. They are still compatible though, so we can just replace this part of the hash.

Example#

password.php:

<?php

$password = "qwertyuiop";

$hash = password_hash($password, PASSWORD_BCRYPT);
// PASSWORD_DEFAULT is equivalent as of now
// https://www.php.net/manual/en/function.password-hash.php

echo $hash;

password.js:

const bcrypt = require("bcrypt");
const exec = require("child_process").exec;

const password = "qwertyuiop";

const cmd = "/usr/local/bin/php ./password.php";

exec(cmd, (err, stdout, stderr) => {
  // See https://en.wikipedia.org/wiki/Bcrypt#Versioning_history
  const hash = stdout.replace("$2y$", "$2a$");

  bcrypt.compare(password, hash).then(function (res) {
    // Should output true
    console.log(res);
  });
});

It's working 👍

stanislas@mbp ~/l/password-hash> node password.js
true

The reverse operation can of course be done using the same technique.

Source: Stack Overflow

Stanislas
Author
Stanislas
I like building things with code and computers

Comments

3Atom feed
Markdown supported
  1. Anonymous

    Thank you, this solution worked perfectly for me!

  2. Luis

    You are my fucking idol. Thanks

    1. Simon

      I second what he said ^