适用于Python的pbkdf2_sha256.verify的NodeJS实现

时间:2018-07-31 13:00:05

标签: python node.js cryptography sha256 pbkdf2

我必须将此Python代码转换为NodeJS:

from passlib.hash import pbkdf2_sha256
pbkdf2_sha256.verify('12345678', '$pbkdf2-sha256$2000$8R7jHOOcs7YWImRM6V1LqQ$CIdNv8YlLlCZfeFJihZs7eQxBsauvVfV05v07Ca2Yzg')
>> True

上面的代码是完整的代码,即没有其他参数/​​设置(只需运行pip install passlib,然后再运行以安装passlib软件包)。

我正在寻找可以通过此积极实施测试的validatePassword函数的正确实现:

validatePassword('12345678', '$pbkdf2-sha256$2000$8R7jHOOcs7YWImRM6V1LqQ$CIdNv8YlLlCZfeFJihZs7eQxBsauvVfV05v07Ca2Yzg')
>> true

这是passlib.hash.pbkdf2_sha256的documentation及其默认参数的值。

我尝试遵循here的回答以及上面的Python代码中的数据,但是解决方案没有通过测试。

我希望此实现有一些帮助(最好使用内置的NodeJS crypto包)。

谢谢。

5 个答案:

答案 0 :(得分:2)

这将起作用:

const crypto = require('crypto')
function validatePassword(secret, format) {
    let parts = format.split('$')
    return parts[4] == crypto.pbkdf2Sync(secret, Buffer.from(parts[3].replace(/\./g, '+') + '='.repeat(parts[3].length % 3), 'base64'),
        +parts[2], 32, parts[1].split('-')[1]).toString('base64').replace(/=/g, '').replace(/\+/g, '.')
}

答案 1 :(得分:0)

您可以使用crypto.pbkdf2本机node.js api

const crypto = require('crypto');
crypto.pbkdf2('secret', 'salt', 100000, 64, 'sha256', (err, derivedKey) => {
  if (err) throw err;
  console.log(derivedKey.toString('hex'));  // '3745e48...08d59ae'
});

它具有以下api:

  • password <string>
  • salt <string>
  • iterations <number>
  • keylen <number>
  • digest <string>
  • callback <Function>
    • err <Error>
    • derivedKey <Buffer>

因此,您将需要像python一样使用输入变量来获得预期的结果。

另一种方法

我玩了输入变量,但收效甚微,我得到的最简单的想法是制作可验证密码的Python脚本,并在node.js中使用child_process.spawn进行调用。

答案 2 :(得分:0)

我无法通过此处的其他答案来解决这个问题,但它们确实使我朝着正确的方向前进。

这是我降落的地方

// eslint-2017
import crypto from 'crypto';
const encode = (password, { algorithm, salt, iterations }) => {
    const hash = crypto.pbkdf2Sync(password, salt, iterations, 32, 'sha256');
    return `${algorithm}$${iterations}$${salt}$${hash.toString('base64')}`;
};
const decode = (encoded) => {
    const [algorithm, iterations, salt, hash] = encoded.split('$');
    return {
        algorithm,
        hash,
        iterations: parseInt(iterations, 10),
        salt,
    };
};
const verify = (password, encoded) => {
    const decoded = decode(encoded);
    const encodedPassword = encode(password, decoded);
    return encoded === encodedPassword;
};
// <algorithm>$<iterations>$<salt>$<hash>
const encoded = 'pbkdf2_sha256$120000$bOqAASYKo3vj$BEBZfntlMJJDpgkAb81LGgdzuO35iqpig0CfJPU4TbU=';
const password = '12345678';
console.info(verify(password, encoded));

我知道这是一篇过时的文章,但这是Google上最好的结果之一,所以我想我会帮助某个在2020年遇到的人。

答案 3 :(得分:0)

基于node-django-hasher,这对我有用(由于使用node-gyp,因此未使用它)

.FirstOrDefault();

答案 4 :(得分:0)

终于解决了。因为 passlib 对 base64 编码的字符串进行了一些转换,所以没有提到的解决方案对我有用。我最终编写了自己的节点模块,并使用 passlib 1.7.4 哈希进行了测试。感谢@kayluhb 将我推向正确的方向!

随意使用它:node-passlib