<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<script>
let intermediateKey;
let publicKey;
let privateKey;
let wrappedKey;
let iv;
async function rsaKeyPair() {
let keyPair = await crypto.subtle.generateKey({
name: "RSA-OAEP",
modulusLength: 4096,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256",
},
true, ["wrapKey", "unwrapKey"]
);
publicKey = keyPair.publicKey;
privateKey = keyPair.privateKey;
}
async function encrypt(secret) {
// generating random intermediate key to encrypt and decrypt the secret
intermediateKey = await crypto.subtle.generateKey({
name: "AES-GCM",
length: 256
},
true, ["encrypt", "decrypt"]
);
// encrypt secret
// ...
// wrap intermediate key (export + encrypt) intermediateKey using publicKey.
iv = crypto.getRandomValues(new Uint8Array(12));
wrappedKey = await crypto.subtle.wrapKey(
"jwk",
intermediateKey,
publicKey, {
name: "AES-GCM",
iv: iv
}
);
}
async function decrypt(cipher) {
// unwrap (decrypt + import) aes key using private key.
intermediateKey = await crypto.subtle.unwrapKey(
"jwk",
wrappedKey,
privateKey, {
name: "AES-GCM",
iv: iv
}, {
name: "AES-GCM"
},
false, ["encrypt", "decrypt"]
);
// decrypt the cipher
// ...
}
async function solve() {
// generate rsa-keypairs
await rsaKeyPair();
// encrypt secret
const cipher = await encrypt("secret");
// decrypt cipher
await decrypt(cipher);
}
solve();
</script>
</body>
</html>
generating RSA-OAEP key pair (according to http://www.w3.org/TR/WebCryptoAPI/#algorithm-overview.)
When the user create a secret, the secret is encrypted using AES-GCM-256 with a randomly generated intermediate key. Finally, this intermediate key is wrapped with the user's public key.
finally unwrap intermediate key & decryption.
the error is generated during unwrapping the intermediate key.
Both, the
wrapKey()
andunwrapKey()
calls lack the proper specification of thewrapAlgo
andunwrapAlgo
parameters, respectively, which are used to specify the algorithm to encrypt the key. In this example, RSA with OAEP is applied, so aRsaOaepParams
object must be used for both parameters.If the parameters are specified correctly in both functions, the AES key will be encrypted and decrypted correctly: