4

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!

Tonke
  • 41
  • 1
  • 3
  • I can't reproduce your error (Safari 11.1.1). Code seems to be working fine here. I get `CbTxsJz5GY6ID70a9Ji1UbhorbDmFEv0FtA58KBiAvCXpBa+D/2uDZv7acbgZtRvLbhAnHenYaJqHIy8WwYaipQsYjB13Ofnvkb5jRVNCdpNbIZ0zcJ8AzrCScPvZ+dF8hZbtsjAmdeBFxWGhd3TdAfJVvo7gn94ndir8A==` in the decrypted buffer, in base64. – Touffy Jul 04 '18 at 12:30
  • 3
    Note that for security reasons, you'll always receive an unhelpful "operationError" no matter what goes wrong with the Web Crypto API. – Touffy Jul 04 '18 at 12:32
  • Ah, that makes sens! Thanks for the feedback, I get this error here on both the latest Firefox and Chromium. The result might be correct, since I replaced the real data with random generated one. – Tonke Jul 04 '18 at 12:55
  • Weird. I do reproduce the error in Chrome. I don't see why. – Touffy Jul 04 '18 at 14:02
  • I've just checked, WebKitGTK+ 2.20.3 seems to work as well. – Tonke Jul 04 '18 at 14:38
  • 2
    Is there a debug mode, to get a more descriptive error message? – Tonke Jul 04 '18 at 15:48

1 Answers1

0

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

rmhrisk
  • 1,814
  • 10
  • 16