Discover how to compare a bcrypt hash generated in PHP with password_hash(), using Node.js and the bcrypt module

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