Javascript 如何在Node.js中复制此PHP哈希实现?
我正在尝试在node.js(LTS-latest--14.x)中重新创建一个最初用PHP(7.2)编写的密码哈希实现。我相信我编写的node.js实现应该做完全相同的事情;但是,node.js实现在循环中第一次传递散列之后有所不同。我错过了什么 PHP实现(我无法改变这一点,因为它是web框架的一部分,现有的身份验证依赖于保持不变的哈希机制):Javascript 如何在Node.js中复制此PHP哈希实现?,javascript,php,node.js,cryptography,Javascript,Php,Node.js,Cryptography,我正在尝试在node.js(LTS-latest--14.x)中重新创建一个最初用PHP(7.2)编写的密码哈希实现。我相信我编写的node.js实现应该做完全相同的事情;但是,node.js实现在循环中第一次传递散列之后有所不同。我错过了什么 PHP实现(我无法改变这一点,因为它是web框架的一部分,现有的身份验证依赖于保持不变的哈希机制): $algo=“sha512”; $salt=“someSalt”; $password='somePassword'; $count=32768; $h
$algo=“sha512”;
$salt=“someSalt”;
$password='somePassword';
$count=32768;
$hash=hash($algo,$salt.$password,TRUE);
//$hash与node.js实现中相应行中的相同
做{
$hash=hash($algo,$hash.$password,TRUE);
//$hash与第一次传递后的node.js实现不同…为什么?
}而(-$count);
Node.js实现:
const crypto=require('crypto');
常量算法='sha512';
常量盐='someSalt';
const password='somePassword';
让计数=32768;
让hash=crypto
.createHash(算法)
.更新(salt+密码)
.摘要(“二进制”);
//散列与这里的PHP实现中的散列相同
做{
hash=crypto.createHash(算法).update(哈希+密码).digest('binary');
//第一次传递后,这两个实现之间的哈希值不同…为什么?
}而(--计数);
编辑:已更新以显示原始Node.js实现,在该实现中,我没有对传递给
update()
的数据进行字符串化,扩展我的评论内容,我认为以下内容可能有效
节点:
const crypto=require('crypto');
常量算法='sha512';
常量盐='someSalt';
const password='somePassword';
让计数=32768;
让hash=crypto
.createHash(算法)
.update(字符串(salt)+字符串(密码))
.摘要(“十六进制”);
//散列与这里的PHP实现中的散列相同
做{
hash=crypto.createHash(算法).update(字符串(哈希)+字符串(密码)).digest('hex');
//第一次传递后,这两个实现之间的哈希值不同…为什么?
}而(--计数);
console.log(散列);
PHP代码:
$algo=“sha512”;
$salt=“someSalt”;
$password='somePassword';
$count=32768;
$hash=bin2hex(hash($algo,$salt.$password,TRUE));
//$hash与node.js实现中相应行中的相同
做{
$hash=bin2hex(hash($algo,$hash.$password,TRUE));
//$hash与第一次传递后的node.js实现不同…为什么?
}而(-$count);
var_dump($hash);
通过节点的输出确认我的发现:
node nodeTest.js
df8202221e5cbff38c16a33945efa8dcb44d0e7267cdf1514cefffb3df321f69ad1d9b01cfb6360391f1de4791e26a179fd165248b4b75699cb2d3395c971351
PHP输出:
php test.php
string(128) "df8202221e5cbff38c16a33945efa8dcb44d0e7267cdf1514cefffb3df321f69ad1d9b01cfb6360391f1de4791e26a179fd165248b4b75699cb2d3395c971351"
在循环中进行哈希运算时,我必须将
'binary'
传递给update()
,因为提供的数据是二进制的
//这里传递给update()的数据是字符串(我相信update默认为utf-8)。
让hash=crypto
.createHash(算法)
.更新(salt+密码)
.摘要(“二进制”);
做{
//传递给update()的数据是二进制的。
hash=crypto.createHash(算法).update(哈希+密码,'binary').digest('binary');
}而(--计数);
信用:@Topaco感谢您为我的问题找到解决方案 尝试将其检查为
.digest('hex')
PHP中的原始实现输出为二进制,而不是十六进制(请参见hash()
函数的最后一个参数为TRUE
)。编辑:我测试它只是为了确定,它肯定会产生一个不同的哈希值。看看你的节点更新,它是二进制输出。在PHP版本中,您不需要。我会尽可能在节点中使用.digest('hex')
,在PHP端使用bin2hex()
。这样,您就可以不使用二进制文件并使用十六进制值。我已经提供了答案以及我测试的输出。PHP 7.4.16和Node 14.16.0在NodeJS代码中,binary'
必须指定为update()
调用中的第二个参数(默认值为UTF8,它会损坏数据,至少对于第二次和后续的update()
调用)。然后这两个代码在我的机器上返回相同的结果。我只是在回应另一条评论时发布了这篇文章,但很遗憾,我无法修改原始的PHP实现,因为它是web框架的一部分,这将破坏现有的身份验证。我只是尝试复制Node.js中的身份验证机制,以便能够从PHP web框架中过渡。