我正在尝试使用Ionic中的SubtleCrypto Web API使用公共密钥加密数据。我以PEM格式导入密钥,然后将其传递到window.crypto.subtle.importKey,然后将结果用于window.crypto.subtle.encrypt

window.crypto.subtle.importKey似乎有问题-尝试导入密钥时出现Uncaught (in promise): DataError

我目前正在使用以下方法导入密钥:

//Get the public key in CryptoKey format
let importedPublicKey = await window.crypto.subtle.importKey(
    "pkcs8",
    this.pemPublicToArrayBuffer(serverPublicKey),
    {
        name: "RSA-OAEP",
        hash: {name: "SHA-256"}
    },
    true,
    []
);

private pemPublicToArrayBuffer(pem) {
  var b64Lines = this.removeLines(pem);
  var b64Prefix = b64Lines.replace('-----BEGIN PUBLIC KEY-----', '');
  var b64Final = b64Prefix.replace('-----END PUBLIC KEY-----', '');

  return this.base64ToArrayBuffer(b64Final);
}

private base64ToArrayBuffer(b64) {
  var byteString = window.atob(b64);
  var byteArray = new Uint8Array(byteString.length);
  for (var i = 0; i < byteString.length; i++) {
    byteArray[i] = byteString.charCodeAt(i);
  }

  return byteArray;
}


有谁可能知道为什么PEM公钥导入密钥失败?

最佳答案

我本人已经花了很多时间来解决这个错误,现在我可以为您(和其他任何人)提供一些好的建议。


您正在将“ pkcs8”作为一种格式传递给importKey方法,但是如果您要导入PUBLIC密钥,则该格式可能是“ spki”(SubjectPublicKeyInfo)一种专用于公共密钥的格式,而“ pkcs8”则应该是用于私钥。这将我们带到下一点:
您从何处获得此密钥?如果要使用OpenSSL cli导出公共密钥(openssl rsa -pubout -in priv.pem -out pub.pem),则将以“ spki”格式(默认值)获取密钥。
如果要导入PUBLIC密钥,则应将[“ encrypt”]作为“用法”参数传递给importKey(而不是空数组),否则最终将出现以下错误之一:“ SyntaxError:无法创建使用指定的密钥用法的密钥”(为密钥指定了错误的用法)或“ InvalidAccessError:key.usages不允许此操作”(用法的空数组)。
这里要记住的是,公钥只能用于[“ encrypt”],而私钥只能用于[“ decrypt”]。虽然我没有尝试导入密钥对,但是据我了解,您应该将“ pkcs8”作为一种格式传递,并将[“ encrypt”,“ decrypt”]用作用法。
即使您正确设置了上述所有设置,您仍然可能会收到讨厌的“未捕获(承诺):DataError”,对我来说,由于格式不匹配,我一直在传递PKCS#1 RSAPublicKey格式的密钥, “ spki”参数。因此,您可能应该从检查密钥开始,以从中获取确切的格式和算法详细信息。


希望这对某人有帮助。
伊万

关于javascript - 来自PEM的SubtleCrypto importKey,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54742554/

10-12 05:33