验证在 php 中生成的 nodejs 中的密码哈希

我的php代码生成一个哈希值,我用它来存储在数据库中。以下是 PHP 代码:password_hash

$hash = password_hash($value, PASSWORD_BCRYPT, array('cost' => $cost));

我想根据nodejs中的此哈希值验证/检查密码。

我看到了很多节点模块(bcrypt,phpass,node-bcrypt),但它们都给了我假的。下面是在php中生成的示例哈希,我试图在nodejs中验证它。

var hash = '$2y$08$9TTThrthZhTOcoHELRjuN.3mJd2iKYIeNlV/CYJUWWRnDfRRw6fD2';

var bcrypt = require('bcrypt');

bcrypt.compare("secret", hash, function(err, res) {
    console.log(res);
});

(这里的秘密是真实密码)

我目前的解决方法是通过节点调用php脚本进行验证(对于任何需要解决方法的人)

var exec = require('child_process').exec;
var cmd = 'php verify.php password encryped_pasword';
exec(cmd, function (error, stdout, stderr) {
  // output is in stdout
  console.log(stdout);
 //If stdout has 1 it satisfies else false
});

这是一个黑客,不是这个问题的好答案。有没有办法在nodejs中验证密码而不使用这样的解决方法?


答案 1

将散列密码中的 $2y$ 替换为 $2a$,则 bcrypt.compare 应该会给出正确的结果。

var hash = '$2y$08$9TTThrthZhTOcoHELRjuN.3mJd2iKYIeNlV/CYJUWWRnDfRRw6fD2';
var bcrypt = require('bcrypt');
hash = hash.replace(/^\$2y(.+)$/i, '$2a$1');
bcrypt.compare("secret", hash, function(err, res) {
    console.log(res);
});

在 ES6 上:

import bcrypt from 'bcrypt';
let hash = '$2y$08$9TTThrthZhTOcoHELRjuN.3mJd2iKYIeNlV/CYJUWWRnDfRRw6fD2';
hash = hash.replace(/^\$2y(.+)$/i, '$2a$1');
bcrypt.compare('secret', hash, function(err, res) {
    console.log(res);
});

答案 2

我知道这个问题已经得到回答,但从评论中似乎需要更多的细节。

php password_hash() 函数生成的 Bcrypt 哈希按如下方式拆分:

$2y$ 08$ 9TTThrthZhTOcoHELRjuN. 3mJd2iKYIeNlV/CYJUWWRnDfRRw6fD2

|     |     |                     |
|     |     Salt                  Hashed Password
|     |
|     Algorithm options (cost, in this case)
|
Algorithm type

从SO上的其他答案来看,虽然Bcrypt的PHP和Node版本使用不同的算法,但哈希输出的唯一区别是前缀。因此,正如@Sudesh所提到的,所需要的只是将a换成a和Bob的叔叔。$2y$$2a$

来源

http://php.net/manual/en/faq.passwords.php

Node 中的 $2y bcrypt 哈希.js

比较 PHP 和 NodeJS 之间的 BCrypt 哈希


推荐