AES-KW est un algorithme d'enveloppement de clé décrit dans RFC3394 . L'algorithme est utilisé pour envelopper, c'est-à-dire chiffrer, une clé. L'entrée, c'est-à-dire la clé à crypter, doit être un multiple entier de 8 octets, s. aussi aquí .
La clé à crypter est passée en SubtleCrypto.wrapKey()
dans le 2ème paramètre key
comme CryptoKey
et doivent donc être exportés avant le cryptage proprement dit. À cette fin, le format dans lequel la clé est exportée est spécifié dans le 1er paramètre format
:
const result = crypto.subtle.wrapKey(format, key, wrappingKey, wrapAlgo);
Dans l'exemple affiché, la clé à envelopper est une clé de 32 octets pour AES-256. Dans raw
la clé satisfait donc au critère de longueur de l'AES-KW. Dans jwk
Toutefois, le critère de la longueur n'est généralement pas respecté :
Si la clé exportée dans jwk
est sérialisé, il a une longueur pour l'utilisation de la clé ["encrypt"]
ou ["decrypt"]
qui se trouve être un multiple entier de 8 octets (112 octets), alors que ce n'est pas le cas pour les utilisations de la clé ["encrypt", "decrypt"]
(122 octets) :
(async () => {
async function getLength(keyUsages) {
var key = await window.crypto.subtle.generateKey(
{name:"AES-GCM", length: 256},
true,
keyUsages
);
var expkey = await crypto.subtle.exportKey("jwk", key)
var expkeySerLen = JSON.stringify(expkey).length;
return {KeyUsages: keyUsages, length: expkeySerLen, lenMod8: expkeySerLen % 8};
}
console.log(await getLength(["encrypt"])); // works
console.log(await getLength(["decrypt"])); // works
console.log(await getLength(["encrypt", "decrypt"])); // doesn't work
})();
C'est très probablement la raison pour laquelle le code avec l'utilisation de la clé ["encrypt"]
ou ["decrypt"]
est exécuté, mais pas le code pour les utilisations clés ["encrypt", "decrypt"]
.
L'essentiel est que l'AES-KW fonctionne. de manière fiable pour le raw
mais pas pour le format jwk
format.
Cependant, le jwk
peut être utilisé dans SubtleCrypto.wrapKey()
pour d'autres algorithmes d'enveloppement, tels que AES-GCM :
(async () => {
let encAlgo = {
name:"AES-GCM",
length:256
};
let wrapAlgo = {
name:"AES-GCM",
length:256
};
let aesGcmParams = {
name:"AES-GCM",
iv: window.crypto.getRandomValues(new Uint8Array(12))
};
let format = "jwk";
let extractable=true;
let keyUsages = ["encrypt", "decrypt"];
let kek = await crypto.subtle.generateKey(
wrapAlgo,
false,
["wrapKey", "unwrapKey"]
);
let key = await window.crypto.subtle.generateKey(
encAlgo,
extractable, // the key is extractable (i.e. can be used in exportKey)
keyUsages
);
console.log("key (CryptoKey)", key);
console.log("key (jwk)", await crypto.subtle.exportKey("jwk", key));
let wrappedKey = await crypto.subtle.wrapKey(
format,
key,
kek,
aesGcmParams
);
console.log("wrappedKey (ArrayBuffer)", wrappedKey);
let unwrappedKey = await crypto.subtle.unwrapKey(
format,
wrappedKey,
kek,
aesGcmParams,
encAlgo,
extractable,
keyUsages
);
console.log("unwrappedKey (jwk) ", await crypto.subtle.exportKey("jwk", unwrappedKey));
})();