Reputation: 1
I am using Webcrypto API
for some cryptographic work on client-side.
Although I cannot wrap and unwrap keys, the browser always returned the following error.
DOMException [OperationError: "The operation failed for an operation-specific reason"
You and I cannot do much with this error, so I pasted my code.
function wrapPrivateKey(privateKey, wrappingKey) {
var iv = window.crypto.getRandomValues(new Uint8Array(12));
return window.crypto.subtle.wrapKey(
"jwk",
privateKey,
wrappingKey,
{
name: "AES-GCM",
length: 256,
iv: iv,
}
)
.then(function (key) {
return {
"key": StringToB64(arrayBufferToString(key)),
"iv": StringToB64(arrayBufferToString(iv))
};
})
.catch(function (err) {
console.error(err);
return false;
});
}
function unwrapPrivateKey(wrappedPrivateKey, unwrappingKey) {
var obj = JSON.parse(B64ToString(wrappedPrivateKey));
var key = stringToArrayBuffer(B64ToString(obj["key"]));
var iv = stringToArrayBuffer(B64ToString(obj["iv"]));
return window.crypto.subtle.unwrapKey(
"jwk",
key,
unwrappingKey,
{
name: "AES-GCM",
length: 256,
iv: iv,
},
{
name: "RSA-OAEP",
hash: {name: "SHA-256"},
},
true,
["encrypt", "decrypt"]
)
.then(function (key) {
return key;
})
.catch(function (err) {
console.error(err);
return false;
});
}
I do not know if the problem is related to converting the key objects to strings. Unfortunately, I need to convert it to a string to persist it in a database.
Upvotes: 0
Views: 1997
Reputation: 799
Here is simple example of key wrapping/unwrapping. This code works in Chrome/Mozilla
const rsaAlg = {
name: "RSA-OAEP",
hash: "SHA-256",
publicExponent: new Uint8Array([1, 0, 1]),
modulusLength: 2048
};
const aesAlg = {
name: "AES-GCM",
length: 256,
iv: crypto.getRandomValues(new Uint8Array(12)),
};
crypto.subtle.generateKey(rsaAlg, true, ["encrypt", "decrypt"])
.then((rsaKeys) => {
return crypto.subtle.generateKey(aesAlg, true, ["encrypt", "decrypt", "wrapKey", "unwrapKey"])
.then((aesKey) => {
return crypto.subtle.wrapKey("jwk", rsaKeys.privateKey, aesKey, aesAlg)
.then((wrappedKey) => {
console.log(wrappedKey); // ArrayBuffer
// Unwrap key
return crypto.subtle.unwrapKey("jwk", wrappedKey, aesKey, aesAlg, rsaAlg, true, ["decrypt"])
})
.then((unwrappedKey) => {
console.log(unwrappedKey);
})
})
})
.catch((err) => {
console.error(err);
})
WebCrypto API is different from one browser to another. It would be better to use some modules which allows to fix it webcrypto-shim, webcrypto-liner
Also I see you use var key = stringToArrayBuffer(B64ToString(obj["key"]));
. But key must be CryptoKey
. If you have raw of symmetric key you have to use importKey
function to create CryptoKey
from raw
Upvotes: 1