比较PHP和NodeJS之间的BCrypt哈希

wol*_*emm 28 php bcrypt node.js

对于我正在处理的应用程序,nodejs需要验证PHP创建的哈希值,反之亦然.

问题是,PHP中生成的哈希(通过Laravel的Hash类,只使用PHP的password_hash函数)在node.js中测试时返回false.

以下node.js脚本:

var bcrypt = require('bcrypt');

var password = 'password';

var phpGeneratedHash  = '$2y$10$jOTwkwLVn6OeA/843CyIHu67ib4RixMa/N/pTJVhOjTddvrG8ge5.';
var nodeGeneratedHash = '$2a$10$ZiBH5JtTDtXqDajO6f4EbeBIXGwtcGg2MGwr90xTH9ki34SV6rZhO';

console.log(
  bcrypt.compareSync(password, phpGeneratedHash)  ? 'PHP passed' : 'PHP failed',
  bcrypt.compareSync(password, nodeGeneratedHash) ? 'nodejs passed' : 'nodejs failed'
);
Run Code Online (Sandbox Code Playgroud)

输出:'PHP失败的nodejs传递',而以下的PHP脚本:

<?php

$password = 'password';

$phpGeneratedHash  = '$2y$10$jOTwkwLVn6OeA/843CyIHu67ib4RixMa/N/pTJVhOjTddvrG8ge5.';
$nodeGeneratedHash = '$2a$10$ZiBH5JtTDtXqDajO6f4EbeBIXGwtcGg2MGwr90xTH9ki34SV6rZhO';

print password_verify($password, $phpGeneratedHash)  ? 'PHP passed' : 'PHP failed';
print password_verify($password, $nodeGeneratedHash) ? 'nodejs passed' : 'nodejs failed';
Run Code Online (Sandbox Code Playgroud)

输出'PHP传递的nodejs传递'.

我已经运行使用PHP 5.5.18在Ubuntu 14.04.1测试,Node.js的v0.10.32和故宫bcrypt模块.

maj*_*rif 59

这失败是因为从php和节点生成的bcrypt哈希的类型是不同的.Laravel生成$2y$while节点生成$2a$.但好消息是之间的唯一区别2a,并2y为他们的前缀.

所以你可以做的是使其中一个前缀类似于另一个.喜欢:

$phpGeneratedHash  = '$2y$10$jOTwkwLVn6OeA/843CyIHu67ib4RixMa/N/pTJVhOjTddvrG8ge5.';
$nodeGeneratedHash = '$2a$10$ZiBH5JtTDtXqDajO6f4EbeBIXGwtcGg2MGwr90xTH9ki34SV6rZhO';
Run Code Online (Sandbox Code Playgroud)

对于这样的事情:

$phpGeneratedHash  = '$2y$10$jOTwkwLVn6OeA/843CyIHu67ib4RixMa/N/pTJVhOjTddvrG8ge5.';
$nodeGeneratedHash = '$2y$10$ZiBH5JtTDtXqDajO6f4EbeBIXGwtcGg2MGwr90xTH9ki34SV6rZhO';
Run Code Online (Sandbox Code Playgroud)

请注意,我$2a$将节点哈希替换为$2y$.你可以这样做:

PHP

$finalNodeGeneratedHash = str_replace("$2a$", "$2y$", $nodeGeneratedHash);
Run Code Online (Sandbox Code Playgroud)

节点

finalNodeGeneratedHash = nodeGeneratedHash.replace('$2a$', '$2y$');
Run Code Online (Sandbox Code Playgroud)

然后比较phpGeneratedHashfinalNodeGeneratedHash.

注意:如果您在PHP中进行比较,建议您更改NodeJS生成的哈希的前缀,$2y$以及在NodeJS中进行比较; 将PHP生成的哈希的前缀更改为$2a$.

  • ... 2年后。@JamesFurey不客气。当我不得不花一些时间做同样的事情时,我发现了这一点。 (3认同)
  • 感谢您的回答,一切都按预期进行!我没想到要查找bcrypt哈希的结构。有什么明显的原因为什么bcrypt模块不执行PHP所允许的两种实现都起作用? (2认同)
  • @wolfemm,简单来说,他们正在使用不同类型/版本的bcrypt。 (2认同)

Nic*_*net 5

我试图计算之前所说的内容以获得有效的代码。如您所见,我不需要更换任何东西。

在 PHP 7.2.4 方面:

<?php
$password = "test123";
    $hash = password_hash($password, PASSWORD_BCRYPT);
    echo $hash; // I get $2y$10$5EaF4lMSCFWe7YqqxyBnR.QmDu1XhoiaQxrOFw.AJZkGCYmpsWDU6
Run Code Online (Sandbox Code Playgroud)

在 nodeJS 方面:

安装 bcryptjs 包:npm i bcryptjs

var bcrypt = require('bcryptjs');
let hash1="$2y$10$5EaF4lMSCFWe7YqqxyBnR.QmDu1XhoiaQxrOFw.AJZkGCYmpsWDU6";
console.log(bcrypt.compareSync("test123", hash1)); // display true
Run Code Online (Sandbox Code Playgroud)