NodeJS pbkdf2Sync 密码具有从 v0.12.7 到 v6.9.1 的可移植性

NodeJS pbkdf2Sync password hasing portability from v0.12.7 to v6.9.1

我一直致力于将一个从节点 v0.12.7 编写的应用程序移植到节点 v6.9.1。

我们正在使用 MEAN 堆栈,并将它们全部升级到最新版本。

除了一个问题,我们已经能够升级所有的东西。我们使用 pbkdf2Sync 方法(内置 express)来散列密码,如下所示:

/**
* Hook a pre save method to hash the password
*/
UserSchema.pre('save', function(next) {
    if (this.password && this.password.length > 6) {
       this.salt = new Buffer(crypto.randomBytes(16).toString('base64'), 'base64');
       this.password = this.hashPassword(this.password);
    }

    next();
});

/**
* Create instance method for hashing a password
*/
UserSchema.methods.hashPassword = function(password) {
   if (this.salt && password) {
      return crypto.pbkdf2Sync(password, this.salt, 10000, 64).toString('base64');
   } else {
    return password;
   }
};

在最新版本中,他们已将编码更改为 utf8,并且还更改了 pbkdf2Sync 以包含强制摘要。我不确定他们还改变了什么。

问题:

mongo数据库中使用较早版本node哈希存储的密码与版本升级后hashPassword函数生成的密码不匹配。

我试过了:

1) 指定编码字符串

2) 使用缓冲区

3) 添加摘要选项作为参数

而且我没有得到与其中任何一个相同的散列密码。

我尝试用多种组合更改 hashPassword 函数。我做过的其中一项尝试是这样的,但没有用。

UserSchema.methods.hashPassword = function (password) {
  if (this.salt && password) {
     return crypto.pbkdf2Sync(password, new Buffer(this.salt, 'base64').toString('binary'), 10000, 64, 'SHA1').toString('base64');
  } else {
    return password;
 }
};

一个测试用例:

哈希密码:ramco@123

盐:d\u001e'��\u0001\u0004\u0012)aq��**G\u000f

我应该得到的结果:kG6uCjSk87I7PrXMko+nS8Mz/78LMilXDMJZI0mzBgi75mBpi8hIkh3+B8CqpuYZdvvs5HWjcNthhhnUA89sCw==

但是我从 hashPassword 函数中得到了一些其他字符串。

我提到了:

git 中的 NodeJS 提交: https://github.com/nodejs/node/commit/b010c8716498dca398e61c388859fea92296feb3

git 中的明确提交: https://github.com/meanjs/mean/commit/61f1a22c91ac15f06143ace6e540b334fa9e3bd6

加密文档: https://nodejs.org/api/crypto.html

How to store crypto pbkdf2 in mongoDB?

还有很多其他网站和论坛,但对我没有帮助。如果可以,请帮助我。

提前致谢。

看起来旧版本的 Node 使用 SHA-1 作为摘要。此外,您应该将盐作为二进制缓冲区传递(我正在使用您的示例中提供的盐字符串,如果您将盐存储为 Base64 编码的二进制文件,您可能可以保留 base64 编码重新按原样使用并且仅明确设置正确的摘要)。

以下会产生预期的结果:

const crypto = require('crypto');

let password = 'ramco@123';
let salt     = `d\u001e'��\u0001\u0004\u0012)aq�**G\u000f`;

let x = crypto.pbkdf2Sync(password, new Buffer(salt, 'binary'), 10000, 64, 'sha1').toString('base64');

console.log(x);