英文:
HKDFExpand in NodeJS
问题
Here are the translated parts:
Javascript:
import crypto from 'crypto';
const salt = 'salt';
const iterations = 100000;
const password = '123';
const masterKey = crypto.pbkdf2Sync(password, salt, iterations, 32, 'sha256');
const stretched = crypto.createHmac('sha256', 'enc').update(masterKey).digest();
console.log(masterKey.toString('hex')) // 5bb4...5990 <- Same
console.log(stretched.toString('hex')) // 82be...6890 <- Different
Python:
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import kdf, hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives.kdf.hkdf import HKDFExpand
salt = 'salt'
iterations = 100000
password = b'123'
kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=bytes(salt, "utf-8"), iterations=iterations, backend=default_backend())
master_key = kdf.derive(password)
hkdf = HKDFExpand(algorithm=hashes.SHA256(), length=32, info=b"enc", backend=default_backend())
stretched = hkdf.derive(master_key)
print(master_key.hex()) # 5bb4...5990 <- Same
print(stretched.hex()) # 5bf9...473b <- Different
I've provided the translated code parts without any additional content.
英文:
I try to implement HKDFExpand
in NodeJS
using crypto
library
The goal is to decrypt encrypted bitwarden
(password manager) password protected export in NodeJS
.
I try to mimic the same behavior in NodeJS
but the expanded key is different from the python version which working for me.
Javascript:
import crypto from 'crypto'
const salt = 'salt'
const iterations = 100000
const password = '123'
const masterKey = crypto.pbkdf2Sync(password, salt, iterations, 32,'sha256');
const streched = crypto.createHmac('sha256', 'enc').update(masterKey).digest();
console.log(masterKey.toString('hex')) // 5bb4...5990 <- Same
console.log(streched.toString('hex')) // 82be...6890 <- Different
Python:
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import kdf, hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives.kdf.hkdf import HKDFExpand
salt = 'salt'
iterations = 100000
password = b'123'
kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=bytes(salt, "utf-8"), iterations=iterations,backend=default_backend())
master_key = kdf.derive(password)
hkdf = HKDFExpand(algorithm=hashes.SHA256(), length=32, info=b"enc", backend=default_backend())
streched = hkdf.derive(master_key)
print(master_key.hex()) # 5bb4...5990 <- Same
print(streched.hex()) # 5bf9...473b <- Different
答案1
得分: 0
I found this function in the Bitwarden source code, and it works
function hkdfExpand(
prk: Buffer,
info: string,
outputByteSize: number
) {
const algorithm = "sha256";
const hashLen = 32;
const prkArr = new Uint8Array(prk);
if (prkArr.length < hashLen) {
throw new Error("prk is too small.");
}
const infoBuf = Buffer.from(info);
const infoArr = new Uint8Array(infoBuf);
let runningOkmLength = 0;
let previousT = new Uint8Array(0);
const n = Math.ceil(outputByteSize / hashLen);
const okm = new Uint8Array(n * hashLen);
for (let i = 0; i < n; i++) {
const t = new Uint8Array(previousT.length + infoArr.length + 1);
t.set(previousT);
t.set(infoArr, previousT.length);
t.set([i + 1], t.length - 1);
previousT = new Uint8Array(hmac(t, prk, algorithm));
okm.set(previousT, runningOkmLength);
runningOkmLength += previousT.length;
if (runningOkmLength >= outputByteSize) {
break;
}
}
return Buffer.from(okm.slice(0, outputByteSize).buffer);
}
英文:
I found this function in bitwarden source code, and it works
function hkdfExpand(
prk: Buffer,
info: string,
outputByteSize: number
) {
const algorithm = "sha256"
const hashLen = 32;
const prkArr = new Uint8Array(prk);
if (prkArr.length < hashLen) {
throw new Error("prk is too small.");
}
const infoBuf = Buffer.from(info);
const infoArr = new Uint8Array(infoBuf);
let runningOkmLength = 0;
let previousT = new Uint8Array(0);
const n = Math.ceil(outputByteSize / hashLen);
const okm = new Uint8Array(n * hashLen);
for (let i = 0; i < n; i++) {
const t = new Uint8Array(previousT.length + infoArr.length + 1);
t.set(previousT);
t.set(infoArr, previousT.length);
t.set([i + 1], t.length - 1);
previousT = new Uint8Array(hmac(t, prk, algorithm));
okm.set(previousT, runningOkmLength);
runningOkmLength += previousT.length;
if (runningOkmLength >= outputByteSize) {
break;
}
}
return Buffer.from(okm.slice(0, outputByteSize).buffer);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论