Google chrome 使用Chromium中的WebCrypto生成RSA密钥对

Google chrome 使用Chromium中的WebCrypto生成RSA密钥对,google-chrome,rsa,chromium,webcrypto-api,Google Chrome,Rsa,Chromium,Webcrypto Api,以下代码适用于Firefox 76.0.1: "use strict" let RSAKeys (async () => { RSAKeys = await crypto.subtle.generateKey({ name: "RSA-OAEP", modulusLength: 3072, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256"}, true, // C

以下代码适用于Firefox 76.0.1:

"use strict"
let RSAKeys
(async () => {
  RSAKeys = await crypto.subtle.generateKey({
      name: "RSA-OAEP",
      modulusLength: 3072,
      publicExponent: new Uint8Array([1, 0, 1]),
      hash: "SHA-256"},
    true,
// Chromium bug causes it to falsely complain that the array is empty. Sometimes adding "encrypt" helps.
    ["wrapKey"])
})()
但在Chromium 80中,我得到:

未捕获(在promise中)DomeException:创建密钥时Usages不能为空


[“wrapKey”]
显然不是空数组,所以它似乎是一个浏览器错误。可能你能证实吗?更重要的是,你知道解决办法吗?(添加
encrypt
用法有帮助,但只是第一次,然后是相同的错误。)它必须是支持包装密钥的非对称密码。根据中的表,RSA-OAEP是唯一的可能性。

我可以在Chromium版本85.0.4162.0上重现该问题:密钥用法
[“wrapKey”]
生成发布的错误消息。但我无法重现添加密钥用法encrypt(即
[“wrapKey”,“encrypt”]
)解决了这个问题(甚至不是第一次)。但是,添加密钥用法unwrapKey(即
[“wrapKey”,“unwrapKey”]
)后,该错误不再发生

返回包含RSA密钥对的for
“RSA-OAEP”
。如果在Firefox浏览器控制台中查看使用密钥用法生成的密钥对
[“wrapKey”,“unwrapKey”]
,可以看到公钥的密钥用法是
[“wrapKey”]
,私钥的密钥用法是
[“unwrapKey”]
。两者都是合理的,因为公钥用于包装,私钥用于展开:

但是,如果您在Firefox浏览器控制台中查看使用密钥用法生成的密钥对,您可以看到公钥的密钥用法保持不变,而私钥的密钥用法为空:

因此,Chromium通过相应的错误消息(显然是指使用空密钥的私钥)防止生成不使用密钥的密钥。与Chromium不同,Firefox显然允许这样做

那是铬臭虫吗?实际上,创建一个没有密钥用法的密钥没有多大意义,因为它不能被使用

Firefox浏览器示例:如果在Firefox浏览器中执行以下代码,则确实会生成密钥对,并且由于公钥的密钥使用wrapKey而包装密钥,但是如果私钥的密钥使用wrapKey丢失,则展开会失败,并出现
InvalidAccessError

var test=async()=>{
试一试{
var mode=document.querySelector('input[name=“keyUsages”]:checked')。值;
var keyUsages=(mode==“wrap”)?[“wrapKey”]:[“wrapKey”,“unwrapKey”]
//创建RSA密钥对
var RSAKeys=await crypto.minute.generateKey(
{name:“RSA-OAEP”,modulesLength:3072,publicExponent:new Uint8Array([0x01,0x00,0x01]),哈希:{name:“SHA-256”},
是的,
关键用法);
//创建要换行的关键点
var keyToWrap=await window.crypto.minute.generateKey(
{名称:“AES-GCM”,长度:128},
是的,
[“加密”、“解密”];
//包裹键
var wrappedKey=await window.crypto.division.wrapKey(
“生的”,
钥匙扣,
RSAKeys.publicKey,
{name:“RSA-OAEP”,散列:{name:“SHA-256”});
//展开键
var unwrappedKey=wait window.crypto.minute.unwrappkey(
“生的”,
拉佩德基,
RSAKeys.privateKey,
{name:“RSA-OAEP”,modulesLength:3072,publicExponent:new Uint8Array([0x01,0x00,0x01]),哈希:{name:“SHA-256”},
{名称:“AES-GCM”,长度:128},
假,,
[“加密”、“解密”];
document.getElementById(“结果”).innerHTML=“用于“+unwrappedKey.algorithm.name+”unwrapped”的密钥。”;
控制台日志(打开包装键);
}捕获(e){
document.getElementById(“结果”).innerHTML=e.name+“:”+e.message;
}
}
.as控制台包装{最大高度:7.0em!重要;}

[“wrapKey”]
[“wrapKey”、“unwrapKey”]
运行


它在chrome 83或更新版本中工作吗?感谢您提供详细的示例性答案。
“unwrapKey”
确实明显丢失了。我唯一的挑剔是,如果规范要求不同的行为,那就是一个bug。但也请参见。虽然这个错误在
[“wrapKey”,“unwrapKey”]
中确实不再发生,但我得到了一个不同的错误:>未捕获(承诺中)DomeException:密钥不是预期的类型,我想是的,但我做了进一步的研究,实际上不是这样。我发现了Chromium和Firefox之间的另一个区别。在Chromium中,第二个错误发生在我尝试导出密钥时。我已经问过了。