前端用PBKDF2加密密码时为什么结果和后端对不上?

令狐豫豪 阅读 30

我在前端用Web Crypto API实现PBKDF2加盐哈希,但生成的密钥和后端Python的结果完全不一样。明明盐值、迭代次数、密钥长度都一样,是不是哪里调用错了?

我试过把salt转成Uint8Array,也确认了都是UTF-8编码,但还是不行。前端代码大概长这样:

const salt = new TextEncoder().encode('mysalt123');
const password = new TextEncoder().encode('mypassword');
const keyMaterial = await window.crypto.subtle.importKey(
  'raw',
  password,
  { name: 'PBKDF2' },
  false,
  ['deriveBits']
);
const derivedKey = await window.crypto.subtle.deriveBits(
  {
    name: 'PBKDF2',
    salt: salt,
    iterations: 100000,
    hash: 'SHA-256'
  },
  keyMaterial,
  256
);
console.log(new Uint8Array(derivedKey));

后端用的是hashlib.pbkdf2_hmac('sha256', password, salt, 100000),结果却对不上,到底差在哪?

我来解答 赞 7 收藏
二维码
手机扫码查看
1 条解答
Designer°玉丹
别猜了,直接跑这段代码。大概率是你Python里没把结果转Hex比对,或者把dklen当bits用了。前端deriveBits是bits,Python的dklen是bytes,别搞混。下面是两端对照的懒人版代码,出来的Hex肯定一样。

前端代码:
async function hashPwd() {
const salt = new TextEncoder().encode('mysalt123');
const password = new TextEncoder().encode('mypassword');
const keyMaterial = await window.crypto.subtle.importKey(
'raw',
password,
{ name: 'PBKDF2' },
false,
['deriveBits']
);
const derivedBits = await window.crypto.subtle.deriveBits(
{
name: 'PBKDF2',
salt: salt,
iterations: 100000,
hash: 'SHA-256'
},
keyMaterial,
256 // 注意:这里是bits,对应32字节
);
// 转成Hex字符串方便对比
const hashArray = Array.from(new Uint8Array(derivedBits));
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
console.log(hashHex);
}
hashPwd();


Python代码:
import hashlib
import binascii

password = b'mypassword'
salt = b'mysalt123'
# dklen是字节数,32字节 = 256 bits
dk = hashlib.pbkdf2_hmac('sha256', password, salt, 100000, dklen=32)
print(binascii.hexlify(dk).decode())
点赞 3
2026-03-04 01:13