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

RSA私钥解包失败:DOMException错误排查求助

问题:解包加密的RSA私钥时抛出DOMException错误

尝试通过用户密码派生的AES密钥加密RSA私钥,在解包时出现错误:DOMException: An invalid or illegal string was specified。

错误原因

RSA-OAEP算法的私钥仅支持decrypt和unwrapKey两种密钥用法,代码中在调用unwrapKey时,为私钥指定了不支持的encrypt用法,导致参数非法。

修复方案

将unwrapKey调用的最后一个参数(密钥用法数组)从["encrypt", "decrypt"]修改为["decrypt"],匹配RSA私钥的合法用法。

修复后的完整代码

const base64ToArrayBuffer = (data) => {
    const binaryKey = atob(data);
    const keyBytes = new Uint8Array(binaryKey.length);

    for (let i = 0; i < binaryKey.length; i++) {
        keyBytes[i] = binaryKey.charCodeAt(i);
    }

    return keyBytes.buffer;
}

const bufferToBase64 = (data) => btoa(String.fromCharCode(... new Uint8Array(data)));

const fn = async () => {
// Generate RSA key pair
  const keyPair = await crypto.subtle.generateKey({
      name: "RSA-OAEP",
      modulusLength: 4096,
      publicExponent: new Uint8Array([1, 0, 1]),
      hash: "SHA-512"
  }, true, ["encrypt", "decrypt"]);

// Encrypt the private key
  const textEncoder = new TextEncoder();
  const salt = new Uint8Array(16);
  crypto.getRandomValues(salt);

  const passwordKey = await crypto.subtle.importKey("raw", textEncoder.encode(window.prompt("password")), "PBKDF2", true, ["deriveKey"]);
  const derivedKey = await crypto.subtle.deriveKey({
      name: "PBKDF2",
      hash: "SHA-256",
      salt,
      iterations: 210000
  }, passwordKey, {
      name: "AES-CBC",
      length: 256
  }, true, ["wrapKey", "unwrapKey"]);
  
  const iv = new Uint8Array(16);
  crypto.getRandomValues(iv);

  const wrappedPrivateKey = await crypto.subtle.wrapKey("pkcs8", keyPair.privateKey, derivedKey, {
      name: "AES-CBC",
      iv
  });

  const b64WrappedPrivateKey = bufferToBase64(wrappedPrivateKey);
  const b64Salt = bufferToBase64(salt);
  const b64IV = bufferToBase64(iv);

  const encryptedPrivateKey = base64ToArrayBuffer(b64WrappedPrivateKey);
  const unwrapSalt = base64ToArrayBuffer(b64Salt);
  const unwrapIV = base64ToArrayBuffer(b64IV);
  
  const unwrapPasswordKey = await crypto.subtle.importKey("raw", textEncoder.encode(window.prompt("password unwrap")), "PBKDF2", true, ["deriveKey"]);
  const unwrappingKey = await crypto.subtle.deriveKey({
      name: "PBKDF2",
      hash: "SHA-256",
      salt: unwrapSalt,
      iterations: 210000
  }, unwrapPasswordKey, {
      name: "AES-CBC",
      length: 256
  }, true, ["wrapKey", "unwrapKey"]);

  try {
    const privateKey = await crypto.subtle.unwrapKey("pkcs8", encryptedPrivateKey, unwrappingKey, {
      name: "AES-CBC",
      iv: unwrapIV
  }, {
      name: "RSA-OAEP",
      hash: "SHA-512"
  }, true, ["decrypt"]); // 此处修改为仅允许decrypt用法

  console.log("Success");
  } catch (err) {
    console.log(err);
  }
};

(async () => {
  await fn();
})()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 04:54:52