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

Sud*_*esh 21 php security bcrypt node.js php-password-hash

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

$hash = password_hash($value, PASSWORD_BCRYPT, array('cost' => $cost));
Run Code Online (Sandbox Code Playgroud)

我想在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);
});
Run Code Online (Sandbox Code Playgroud)

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

我目前的解决方法是通过节点调用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
});
Run Code Online (Sandbox Code Playgroud)

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

小智 38

用$ 2a $替换哈希密码中的$ 2y $,然后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);
});
Run Code Online (Sandbox Code Playgroud)

在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);
});
Run Code Online (Sandbox Code Playgroud)

  • `$2a$` 或 `$2y$` 只是一个前缀,表示正在使用的算法的版本。在 2011 年 PHP 实现中出现了一个重大错误,有人主动将原始前缀 `$2a$` 更改为 `$2x$`,以表明散列是使用有漏洞的算法和 `$2y$` 完成的表明它是正确的。除了 PHP 之外,没有人接受推荐。这就是为什么 node.js bcrypt 不能识别该前缀而 PHP crypt_blowfish 可以识别的原因。 (5认同)
  • 这对我非常感谢!虽然有兴趣知道为什么如果有人知道这是必要的? (3认同)

Ale*_*ark 21

我知道这已经得到了回答,但从评论中可以看出需要更多细节.

php password_hash()函数生成的Bcrypt哈希值分为以下几种:

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

|     |     |                     |
|     |     Salt                  Hashed Password
|     |
|     Algorithm options (cost, in this case)
|
Algorithm type
Run Code Online (Sandbox Code Playgroud)

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

来源

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

Node.js中的$ 2y bcrypt哈希值

比较PHP和NodeJS之间的BCrypt哈希