简体   繁体   中英

nodejs crypto-js vs python sha256

I have a problem with crypto-js vs python sha256. It would like to write a nodejs client for duplicati. So I tried to port some python code to js.

https://github.com/Pectojin/duplicati-client/blob/master/auth.py#L136

Javascript

const CryptoJS = require('crypto-js');

function sha256(to_sign) {  
    var hash = CryptoJS.SHA256(to_sign.toString());
    var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
    return hashInBase64.toString('utf-8');
}

let salt = "ZAwQqEAAwR78oZOxFu0nVH2FLy/BnulVxhuu9IOnBwg="
let salt2 = "YQ=="
let password = "abc"

let saltedpwd = sha256(Buffer.concat([Buffer.from(password),Buffer.from(salt,'base64')]));
let saltedpwd2 = sha256(Buffer.concat([Buffer.from(password),Buffer.from(salt2,'base64')]));

let new_password = saltedpwd.toString('base64');
let new_password2 = saltedpwd2.toString('base64');
console.log(new_password)
console.log(new_password2)

returns:

pw1: 0udYFffMXd2QWW9dVXbFl3qp/6lnRcnspr4M1VEtgJA=
pw2: XD9nt/qE374RGDh8rRR5OSmEWlvHwAgMTYMJ03uqaNA=

Python

import base64
import hashlib
import sys

password = "abc"
salt = "ZAwQqEAAwR78oZOxFu0nVH2FLy/BnulVxhuu9IOnBwg="
salt2 = "YQ=="

salt_password = password.encode() + base64.b64decode(salt)
saltedpwd = hashlib.sha256(salt_password).digest()
print (base64.b64encode(saltedpwd).decode('utf-8'))

salt_password2 = password.encode() + base64.b64decode(salt2)
saltedpwd2 = hashlib.sha256(salt_password2).digest()
print (base64.b64encode(saltedpwd2).decode('utf-8'))

returns:

pw1: v9bAzxPatGzA2W7ORkraUvh+nyXotWXItAKpawGSo+A=
pw2: XD9nt/qE374RGDh8rRR5OSmEWlvHwAgMTYMJ03uqaNA=

as you can see, pw2 with the very simple base64 salt is both the same. the salt from pw1 comes from the duplicati server, so I can't control it...

I've tried some many combinations of encoding, CryptoJS options, so I'm at the point where I will soon stop my 'project'... :(

Can you please give me any advice, what I'm doing wrong? I would be glad about any information.

Regards, Benjamin

You're 99% of the way there, I think the fix is a one liner (isn't it so often!).

We just have to change

var hash = CryptoJS.SHA256(to_sign.toString());

to

var hash = CryptoJS.SHA256(CryptoJS.lib.WordArray.create(to_sign));

I believe this is because we want to convert directly from the buffer we created by concatenating the password and salt, rather than converting to a string, which is causing the wrong hash to be computed.

In any case, we get the same output as the Python code, which is what we want, ie

v9bAzxPatGzA2W7ORkraUvh+nyXotWXItAKpawGSo+A=
XD9nt/qE374RGDh8rRR5OSmEWlvHwAgMTYMJ03uqaNA=

The new code would look like this in Node.js:

const CryptoJS = require('crypto-js');

function sha256(to_sign) {  
    var hash = CryptoJS.SHA256(CryptoJS.lib.WordArray.create(to_sign));
    var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
    return hashInBase64.toString('utf-8');
}

let salt = "ZAwQqEAAwR78oZOxFu0nVH2FLy/BnulVxhuu9IOnBwg="
let salt2 = "YQ=="
let password = "abc"

let saltedpwd = sha256(Buffer.concat([Buffer.from(password),Buffer.from(salt,'base64')]));
let saltedpwd2 = sha256(Buffer.concat([Buffer.from(password),Buffer.from(salt2,'base64')]));

let new_password = saltedpwd.toString('base64');
let new_password2 = saltedpwd2.toString('base64');
console.log(new_password)
console.log(new_password2)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM