我正在尝试使用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公钥导入失败吗?
答案 0 :(得分:1)
我本人花了很多时间来解决这个错误,现在我可以为您(和其他任何人)提供一些好的建议。
您正在将“ 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”,对我来说,这是由于格式不匹配,我一直在传递密钥带有“ spki”参数的PKCS#1 RSAPublicKey格式。因此,您可能应该从检查密钥开始,以从中获取确切的格式和算法详细信息。
希望这对某人有帮助。 伊万