I'm attempting to recreate a password hashing implementation in node.js (LTS latest--14.x) that was originally written in PHP (7.2). I believe the node.js implementation that I've written should do the exact same thing; however, the node.js implementation differs after the first pass of the hash in the loop. What am I missing here?
PHP implementation (I cannot change this since it's part of a web framework and existing authentication relies on the hashing mechanism staying the same):
$algo = "sha512";
$salt = "someSalt";
$password = 'somePassword';
$count = 32768;
$hash = hash($algo, $salt . $password, TRUE);
// $hash is the same as in the corresponding line in the node.js implementation
do {
$hash = hash($algo, $hash . $password, TRUE);
// $hash differs from the node.js implementation after the first pass here... why?
} while (--$count);
Node.js implementation:
const crypto = require('crypto');
const algorithm = 'sha512';
const salt = 'someSalt';
const password = 'somePassword';
let count = 32768;
let hash = crypto
.createHash(algorithm)
.update(salt + password)
.digest('binary');
// hash is the same as in the PHP implementation here
do {
hash = crypto.createHash(algorithm).update(hash + password).digest('binary');
// hash differs between the two implementations after the first pass here... why?
} while (--count);
EDIT: Updated to show the original Node.js implementation where I did not stringify data being passed to update().
.digest('hex')hash()function isTRUE). EDIT: I tested it just to be sure, and it definitely results in a different hash still..digest('hex')where possible in NODE, and dobin2hex()in PHP's side. That way you can keep the binary's out and work with the HEX valuesbinary'must be specified as the second parameter in theupdate()calls (default is UTF8, which corrupts the data, at least for the 2nd and subsequentupdate()calls). Then both codes return the same result on my machine.