【发布时间】:2021-07-03 14:10:30
【问题描述】:
我正在尝试在最初用 PHP (7.2) 编写的 node.js (LTS latest--14.x) 中重新创建密码哈希实现。我相信我编写的 node.js 实现应该做同样的事情;但是,在循环中第一次通过哈希之后,node.js 的实现会有所不同。我在这里错过了什么?
PHP 实现(我无法更改它,因为它是 Web 框架的一部分,并且现有的身份验证依赖于保持不变的散列机制):
$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 实现:
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);
编辑:更新以显示原始 Node.js 实现,其中我没有对传递给 update() 的数据进行字符串化。
【问题讨论】:
-
试试看
.digest('hex') -
PHP 中的原始实现输出为二进制,而不是十六进制(参见
hash()函数的最后一个参数是TRUE)。编辑:我测试它只是为了确定,它肯定会产生不同的哈希值。 -
看看你的节点更新它字符串化的二进制输出。在 PHP 版本中你没有。我会尽可能在 NODE 中使用
.digest('hex'),并在 PHP 端使用bin2hex()。这样您就可以保留二进制文件并使用 HEX 值 -
我已经提供了一个答案以及我的测试输出。 PHP 7.4.16 和节点 14.16.0
-
在 NodeJS 代码中,
binary'必须指定为update()调用中的第二个参数(默认为 UTF8,这会破坏数据,至少对于第二次和后续的update()调用) )。然后两个代码在我的机器上返回相同的结果。
标签: javascript php node.js cryptography