You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NodeJS实现HKDFExpand与Python版本结果不一致问题求助

Node.js crypto实现HKDFExpand与Python版本结果不一致问题

我尝试在NodeJS中使用crypto库实现HKDFExpand,目标是解密Bitwarden(密码管理器)的加密密码保护导出文件。复刻Python版本的行为时,生成的扩展密钥结果和Python版本不一样。

原代码对比

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 <- 结果一致
console.log(streched.toString('hex')) // 82be...6890 <- 结果不同

Python代码

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import 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 <- 结果一致
print(streched.hex()) # 5bf9...473b <- 结果不同

问题原因

你的Node.js代码完全搞反了HKDF扩展步骤的参数,并且缺少了HKDF规范要求的后缀字节:

  1. HKDFExpand的核心是用主密钥(masterKey)作为HMAC的密钥,而不是把"enc"作为密钥
  2. 标准HKDF扩展步骤中,每一轮的输入需要拼接一个单字节的计数器(第一轮是0x01),Python的HKDFExpand会自动处理这个逻辑

修正后的Node.js代码

import crypto from 'crypto'

const salt = 'salt'
const iterations = 100000
const password = '123'

const masterKey = crypto.pbkdf2Sync(password, salt, iterations, 32,'sha256');
// 构造HKDFExpand的输入:info字符串 + 计数器字节0x01
const infoBuffer = Buffer.from('enc', 'utf8');
const hmacInput = Buffer.concat([infoBuffer, Buffer.from([0x01])]);
// 用masterKey作为HMAC密钥,更新构造好的输入
const streched = crypto.createHmac('sha256', masterKey).update(hmacInput).digest();

console.log(masterKey.toString('hex')) // 和Python结果一致
console.log(streched.toString('hex')) // 现在和Python的5bf9...473b完全匹配

验证说明

修正后的代码严格遵循HKDF扩展步骤的规范:

  • PRK(伪随机密钥)就是PBKDF2生成的masterKey
  • 生成T(1) = HMAC-SHA256(PRK, "enc" || 0x01)
  • 取T(1)的前32字节(正好是SHA256的输出长度)作为最终扩展密钥,和Python的HKDFExpand行为完全一致

内容的提问来源于stack exchange,提问作者anonymous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 19:22:33