Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/246.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在Node.js中复制此PHP哈希实现?_Javascript_Php_Node.js_Cryptography - Fatal编程技术网

Javascript 如何在Node.js中复制此PHP哈希实现?

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

我正在尝试在node.js(LTS-latest--14.x)中重新创建一个最初用PHP(7.2)编写的密码哈希实现。我相信我编写的node.js实现应该做完全相同的事情;但是,node.js实现在循环中第一次传递散列之后有所不同。我错过了什么

PHP实现(我无法改变这一点,因为它是web框架的一部分,现有的身份验证依赖于保持不变的哈希机制):

$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框架中过渡。