问题
The following code works in 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"])
})()
but in Chromium 80 I get:
Uncaught (in promise) DOMException: Usages cannot be empty when creating a key.
["wrapKey"]
clearly isn't an empty array, so it seems to be a browser bug. Probably this one. Can you confirm? And more importantly, do you know a workaround? (Adding the encrypt
usage helped but only the first time, then the same error.) It has to be an asymmetric cipher supporting wrapping keys. According to the table in the relevant chapter of the spec, RSA-OAEP is the only possibility.
回答1:
I can reproduce the issue on Chromium version 85.0.4162.0: The key usage ["wrapKey"]
generates the posted error message. But I can't reproduce that an adding of the key usage encrypt (i.e. ["wrapKey", "encrypt"]
) solves the problem (not even the fist time). However, with the addition of the key usage unwrapKey (i.e. ["wrapKey", "unwrapKey"]
) the error no longer occurs.
SubtleCrypto.generateKey() returns a CryptoKeyPair for "RSA-OAEP"
that contains the RSA key pair. If you look in the Firefox browser console at the key pair generated with the key usage ["wrapKey", "unwrapKey"]
, you can see that the key usage of the public key is ["wrapKey"]
and that of the private key is ["unwrapKey"]
. Both are plausible, since the public key is used for wrapping and the private key for unwrapping:
However, if you look in the Firefox browser console at the key pair generated with the key usage ["wrapKey"]
, you can see that the key usage of the public key is unchanged ["wrapKey"]
, while that of the private key is empty:
So Chromium prevents the generation of a key without key usage by the corresponding error message (which obviously refers to the private key with the empty key usage). In contrast to Chromium, Firefox obviously allows this.
Now is that a Chromium bug? Actually it makes not much sense to create a key without a key usage, because it cannot be used!
Example for Firefox browser: If the following code is executed in the Firefox browser, the key pair is indeed generated and a key is wrapped because of the key usage wrapKey for the public key, but the unwrapping fails with an InvalidAccessError
if the key usage unwrapKey for the private key is missing:
var test = async () => {
try {
var mode = document.querySelector('input[name="keyUsages"]:checked').value;
var keyUsages = (mode === "wrap") ? ["wrapKey"] : ["wrapKey", "unwrapKey"]
// Create RSA key pair
var RSAKeys = await crypto.subtle.generateKey(
{name: "RSA-OAEP", modulusLength: 3072, publicExponent: new Uint8Array([0x01, 0x00, 0x01]), hash: {name: "SHA-256"}},
true,
keyUsages);
// Create key to wrap
var keyToWrap = await window.crypto.subtle.generateKey(
{name: "AES-GCM", length: 128},
true,
["encrypt", "decrypt"]);
// Wrap key
var wrappedKey = await window.crypto.subtle.wrapKey(
"raw",
keyToWrap,
RSAKeys.publicKey,
{name: "RSA-OAEP", hash: {name: "SHA-256"}});
// Unwrap key
var unwrappedKey = await window.crypto.subtle.unwrapKey(
"raw",
wrappedKey,
RSAKeys.privateKey,
{name: "RSA-OAEP", modulusLength: 3072, publicExponent: new Uint8Array([0x01, 0x00, 0x01]), hash: {name: "SHA-256"}},
{name: "AES-GCM", length: 128},
false,
["encrypt", "decrypt"]);
document.getElementById("result").innerHTML = "Secret key for " + unwrappedKey.algorithm.name + " unwrapped.";
console.log(unwrappedKey);
} catch(e) {
document.getElementById("result").innerHTML = e.name + ": " + e.message;
}
}
.as-console-wrapper { max-height: 7.0em !important; }
<!DOCTYPE html>
<html>
<body height="200">
<input type="radio" name="keyUsages" value="wrap" checked="true"> ["wrapKey"]
<input type="radio" name="keyUsages" value="wrapUnwrap"> ["wrapKey", "unwrapKey"]
<button onclick="test()">Run</button><br/>
<p id="result"></p>
</body>
</html>
Therefore I would not classify this as a bug (but that's just my opinion).
来源:https://stackoverflow.com/questions/62113043/generate-rsa-key-pair-with-webcrypto-in-chromium