Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NodeJS implementation for Python's pbkdf2_sha256.verify

I have to translate this Python code to NodeJS:

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

The code above is the entire code, i.e. there is no othe parameters/settings (just run pip install passlib before you run it to install the passlib package).

I am looking for the correct implementation of validatePassword function in Node that will pass this positive implementation test:

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

Here is the documentation of the passlib.hash.pbkdf2_sha256 with its default parameters' values.

I tried to follow the answers from here with the data from the Python code above, but that solutions didn't pass the test.

I would appreciate some help with this implementation (preferably using built-in NodeJS crypto package).

Thank you in advance.

like image 379
Alexander Avatar asked Jul 31 '18 13:07

Alexander


2 Answers

This would work:

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, '.')
}
like image 87
shaylevi2 Avatar answered Nov 19 '22 22:11

shaylevi2


I was not able to get this working with the other answers here, but they did lead me in the right direction.

Here's where I landed:

// 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));

I know this is an old post, but it's one of the top results on Google, so figured I'd help someone out that comes across this in 2020.

like image 21
kayluhb Avatar answered Nov 19 '22 22:11

kayluhb