Python 的 pbkdf2_sha256.verify 的 NodeJS 实现
NodeJS implementation for Python's pbkdf2_sha256.verify
我必须将此 Python 代码翻译成 NodeJS:
from passlib.hash import pbkdf2_sha256
pbkdf2_sha256.verify('12345678', '$pbkdf2-sha25600R7jHOOcs7YWImRM6V1LqQ$CIdNv8YlLlCZfeFJihZs7eQxBsauvVfV05v07Ca2Yzg')
>> True
上面的代码是完整的代码,即没有其他 parameters/settings(只是 运行 pip install passlib
在你 运行 安装 passlib
包裹)。
我正在寻找 Node 中 validatePassword
函数的正确实现,它将通过这个积极的实现测试:
validatePassword('12345678', '$pbkdf2-sha25600R7jHOOcs7YWImRM6V1LqQ$CIdNv8YlLlCZfeFJihZs7eQxBsauvVfV05v07Ca2Yzg')
>> true
这是 passlib.hash 的 documentation。pbkdf2_sha256 及其默认参数值。
我尝试使用上面 Python 代码中的数据来遵循 here 的答案,但是这些解决方案没有通过测试。
我希望能为这个实现提供一些帮助(最好使用内置的 NodeJS crypto
包)。
提前致谢。
可以使用crypto.pbkdf2
原生node.jsapi
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 脚本来验证密码并在 [=51= 中使用 child_process.spawn
调用它].
这可行:
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, '.')
}
我无法将此与此处的其他答案一起使用,但它们确实引导我朝着正确的方向前进。
这是我着陆的地方:
// 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_sha2560000$bOqAASYKo3vj$BEBZfntlMJJDpgkAb81LGgdzuO35iqpig0CfJPU4TbU=';
const password = '12345678';
console.info(verify(password, encoded));
我知道这是一个旧 post,但它是 Google 上的最佳结果之一,所以我想我会帮助 2020 年遇到这个问题的人。
这对我有用,基于 node-django-hasher(没有使用它,因为依赖于 node-gyp)
function validatePassword(plain, hashed) {
const parts = hashed.split('$');
const salt = parts[2];
const iterations = parseInt(parts[1]);
const keylen = 32;
const digest = parts[0].split('_')[1];
const value = parts[3];
const derivedKey = crypto.pbkdf2Sync(plain, salt, iterations, keylen, digest);
return value === Buffer.from(derivedKey, 'binary').toString('base64');
}
终于解决了。因为 passlib 对我提到的解决方案的 base64 编码字符串 none 做了一些转换。我最终编写了自己的节点模块,并使用 passlib 1.7.4 哈希进行了测试。感谢@kayluhb 将我推向正确的方向!
随意使用:node-passlib
我必须将此 Python 代码翻译成 NodeJS:
from passlib.hash import pbkdf2_sha256
pbkdf2_sha256.verify('12345678', '$pbkdf2-sha25600R7jHOOcs7YWImRM6V1LqQ$CIdNv8YlLlCZfeFJihZs7eQxBsauvVfV05v07Ca2Yzg')
>> True
上面的代码是完整的代码,即没有其他 parameters/settings(只是 运行 pip install passlib
在你 运行 安装 passlib
包裹)。
我正在寻找 Node 中 validatePassword
函数的正确实现,它将通过这个积极的实现测试:
validatePassword('12345678', '$pbkdf2-sha25600R7jHOOcs7YWImRM6V1LqQ$CIdNv8YlLlCZfeFJihZs7eQxBsauvVfV05v07Ca2Yzg')
>> true
这是 passlib.hash 的 documentation。pbkdf2_sha256 及其默认参数值。
我尝试使用上面 Python 代码中的数据来遵循 here 的答案,但是这些解决方案没有通过测试。
我希望能为这个实现提供一些帮助(最好使用内置的 NodeJS crypto
包)。
提前致谢。
可以使用crypto.pbkdf2
原生node.jsapi
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 脚本来验证密码并在 [=51= 中使用 child_process.spawn
调用它].
这可行:
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, '.')
}
我无法将此与此处的其他答案一起使用,但它们确实引导我朝着正确的方向前进。
这是我着陆的地方:
// 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_sha2560000$bOqAASYKo3vj$BEBZfntlMJJDpgkAb81LGgdzuO35iqpig0CfJPU4TbU=';
const password = '12345678';
console.info(verify(password, encoded));
我知道这是一个旧 post,但它是 Google 上的最佳结果之一,所以我想我会帮助 2020 年遇到这个问题的人。
这对我有用,基于 node-django-hasher(没有使用它,因为依赖于 node-gyp)
function validatePassword(plain, hashed) {
const parts = hashed.split('$');
const salt = parts[2];
const iterations = parseInt(parts[1]);
const keylen = 32;
const digest = parts[0].split('_')[1];
const value = parts[3];
const derivedKey = crypto.pbkdf2Sync(plain, salt, iterations, keylen, digest);
return value === Buffer.from(derivedKey, 'binary').toString('base64');
}
终于解决了。因为 passlib 对我提到的解决方案的 base64 编码字符串 none 做了一些转换。我最终编写了自己的节点模块,并使用 passlib 1.7.4 哈希进行了测试。感谢@kayluhb 将我推向正确的方向!
随意使用:node-passlib