问题
I have the following code to decrypt AES encrypted data with the Javascript Webcrypto-API, but it results in an "OperationError" with the message "The operation failed for an operation-specific reason":
function loadHexToArrybuffer(hex)
{
return new Uint8Array(hex.match(/[\da-f]{2}/gi).map(h => parseInt(h, 16)));
}
var iv = loadHexToArrybuffer("47b79d24e3ec47c528abdaed8f3fafde");
var rawKey = loadHexToArrybuffer("8af4d72873e4016cd73a1d5b851e9cb2");
var encryptedData = loadHexToArrybuffer("2bb7a12a7e59f9fa3c3d4ff0eb502cde3187338cc3137af785995b364fc5b3fe9c208f225c7472bb3de55de18a665863f63030d652b870c4610a70bc771e8bc584df7c3bd2ce3fc1940115e556178e740891f7cac450204a4959916ac9c9cd5aedd92cc7e74a7a581a6d47a6c29fb46eee13ffd3f70616844f8e2bb929c60ad9")
async function test()
{
var algorithm = {name: "AES-CBC", iv: iv};
var key = await window.crypto.subtle.importKey("raw", rawKey, algorithm, false, ["decrypt"]);
try
{
var decrypted = await window.crypto.subtle.decrypt(algorithm, key, encryptedData);
}
catch (e)
{
console.log(e); // OperationError: The operation failed for an operation-specific reason
}
}
test();
Can anybody help me out here? Thanks ahead!
回答1:
You do not state what browser and version you are using, each version supports a different set of algorithms.
If you want a quick test on what each supports see: https://peculiarventures.github.io/pv-webcrypto-tests/
With that said, my first thought is I would not use CBC unless interoperability with an existing system that only uses CBC is necessary. You should look at AES-GCM instead, it is an authenticated mode of encryption which protects from certain attacks that plain CBC will not and is less error prone on usage.
Here is an encrypt example of GCM:
window.crypto.subtle.encrypt(
{
name: "AES-GCM",
//Don't re-use initialization vectors!
//Always generate a new iv every time your encrypt!
//Recommended to use 12 bytes length
iv: window.crypto.getRandomValues(new Uint8Array(12)),
//Additional authentication data (optional)
additionalData: ArrayBuffer,
//Tag length (optional)
tagLength: 128, //can be 32, 64, 96, 104, 112, 120 or 128 (default)
},
key, //from generateKey or importKey above
data //ArrayBuffer of data you want to encrypt
)
.then(function(encrypted){
//returns an ArrayBuffer containing the encrypted data
console.log(new Uint8Array(encrypted));
})
.catch(function(err){
console.error(err);
});
If you need to use CBC here are some good examples on usage: https://github.com/diafygi/webcrypto-examples#aes-cbc
来源:https://stackoverflow.com/questions/51172513/webcrypto-aes-cbc-decrypt-operation-error-the-operation-failed-for-an-operati