1

我正在尝试使用预先生成的 SubtleCrypto 解密字符串

我没有得到解密的文本,而是得到了错误:无法在“SubtleCrypto”上执行“解密”:参数 2 不是“CryptoKey”类型。

console.log(window.crypto.subtle.decrypt({name:"AES-CBC", iv:""}, "1234567890123456", "i4+WxNH8XYMnAm7RsRkfOw=="));

我已经尝试研究该错误,但没有遇到与此类基本示例相关的任何内容。我究竟做错了什么?

4

1 回答 1

2

参数类型错误:IV 和数据必须传递为BufferSource,键为CryptoKey,请参阅SubtleCrypto.decrypt()。ACryptoKey由 返回SubtleCrypto.importKey(),用于导入密钥。

WebCrypto API(作为低级 API)不支持数据转换,例如 Base64 编码数据或字符串到BufferSource,因此必须使用其他辅助方法。

以下代码解密密文:

var keyData = str2ab("1234567890123456");
var iv = new Uint8Array(16).buffer;
var ciphertext = b642ab("i4+WxNH8XYMnAm7RsRkfOw==");

(async () => {
  var decrypted = await decrypt();
  var decryptedStr = new TextDecoder().decode(decrypted);
  console.log(decryptedStr);
})();

async function decrypt() {
  var key = await importKey();
  try {
    return await crypto.subtle.decrypt(
      { name: "AES-CBC", iv: iv },
      key,
      ciphertext
    );
  } catch (ex) {
    console.error("Error: Name: ", ex.name, ", Message: ", ex.message);
  }
}

async function importKey() {
  var key = await crypto.subtle.importKey(
    "raw",
    keyData,
    { name: "AES-CBC" },
    true,
    ["decrypt", "encrypt"]
  );
  return key;
}

// Helper -----------------------------------------------

// https://stackoverflow.com/a/11058858
function str2ab(str) {
  const buf = new ArrayBuffer(str.length);
  const bufView = new Uint8Array(buf);
  for (let i = 0, strLen = str.length; i < strLen; i++) {
    bufView[i] = str.charCodeAt(i);
  }
  return buf;
}

// https://stackoverflow.com/a/21797381/9014097
function b642ab(base64) {
  var binary_string = window.atob(base64);
  var len = binary_string.length;
  var bytes = new Uint8Array(len);
  for (var i = 0; i < len; i++) {
    bytes[i] = binary_string.charCodeAt(i);
  }
  return bytes.buffer;
}

于 2021-05-19T20:30:39.047 回答