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

如何用浏览器Web Crypto API的PBKDF2获得与SJCL/CyberChef一致结果?

在Firefox的Web Crypto API中实现与sjcl/CyberChef一致的PBKDF2密钥派生

要让Web Crypto API的PBKDF2结果和sjcl 1.0.8、CyberChef完全匹配,核心是严格对齐所有参数和编码方式,以下是具体实现步骤和代码:

关键参数对应

先明确三方一致的参数:

  • 输入密码:test(UTF-8编码)
  • 盐值:test(UTF-8编码)
  • 迭代次数:10000
  • 派生密钥长度:256位(32字节)
  • 哈希算法:SHA-256

完整实现代码

async function derivePBKDF2Key() {
  // 1. 将密码和盐转换为Web Crypto需要的ArrayBuffer(UTF-8编码)
  const encoder = new TextEncoder();
  const password = encoder.encode('test');
  const salt = encoder.encode('test');

  // 2. 导入密码为CryptoKey对象
  const cryptoKey = await crypto.subtle.importKey(
    'raw', // 密码的格式:原始二进制
    password,
    { name: 'PBKDF2' }, // 指定算法为PBKDF2
    false, // 是否允许导出密钥(这里不需要,设为false)
    ['deriveBits'] // 允许的操作:派生比特数据
  );

  // 3. 使用PBKDF2派生密钥数据
  const derivedBits = await crypto.subtle.deriveBits(
    {
      name: 'PBKDF2',
      salt: salt,
      iterations: 10000,
      hash: 'SHA-256' // Web Crypto的哈希算法名称带连字符,注意格式
    },
    cryptoKey,
    256 // 派生的密钥长度(单位:位)
  );

  // 4. 将ArrayBuffer转换为十六进制字符串(匹配sjcl和CyberChef的输出格式)
  const hexString = Array.from(new Uint8Array(derivedBits))
    .map(byte => byte.toString(16).padStart(2, '0'))
    .join('');
  
  console.log(hexString); // 输出:1dee9f26ad603dc9260a3071242ef1a46270a975aff83c2178ff88974756d83b
}

// 执行派生
derivePBKDF2Key();

注意事项

  1. 编码一致性:必须使用UTF-8编码将字符串转二进制,sjcl和CyberChef默认都是UTF-8,不要用ASCII或其他编码。
  2. 哈希算法名称:Web Crypto中SHA-256的名称是'SHA-256'(带连字符),写成'SHA256'会导致算法不匹配。
  3. 密钥长度单位:deriveBits的第三个参数是位,256位对应32字节,和sjcl的256参数完全对应。
  4. 迭代次数:必须严格设置为10000,迭代次数不同会直接导致结果差异。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 02:00:07