Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to decrypt data from the result of an IE 11 encrypt operation using AES-GCM

I've managed to encrypt some data with AES-GCM using IE 11 on Windows 10 but I can't get decryption to work. Example encryption JS code:

let plainText = new Uint8Array([1]);
let key;
let keyBuf = window.msCrypto.getRandomValues(new Uint8Array(32));
let iv = window.msCrypto.getRandomValues(new Uint8Array(12));
let additionalData = window.msCrypto.getRandomValues(new Uint8Array(16));
let encResult;
let importOp = window.msCrypto.subtle.importKey('raw', 
    keyBuf,
    { name: 'AES-GCM' }, 
    false, 
    ['encrypt', 'decrypt']);
importOp.oncomplete = function(e) {
    key = e.target.result;
    let encryptOp = window.msCrypto.subtle.encrypt({
        name: 'AES-GCM',
        iv: iv,
        tagLength: 128,
        additionalData: additionalData
    }, key, plainText);
    encryptOp.oncomplete = function (e) {
        encResult = e.target.result;
    };
};

The resulting item (encResult) is an AesGcmEncryptResult, which has the encrypted value and the tag in 2 different properties. As I understand it, I need to concatenate these and pass them as the cipher text to decrypt, as in:

let cipherText = new Uint8Array(plainText.length + 16); // tagLength / 8
cipherText.set(new Uint8Array(encResult.ciphertext), 0);
cipherText.set(new Uint8Array(encResult.tag), plainText.length);
let decryptOp = window.msCrypto.subtle.decrypt({
    name: 'AES-GCM',
    iv: iv,
    tagLength: 128,
    additionalData: additionalData
}, key, cipherText);

I then wire up oncomplete and onerror and onerror fires. Unfortunately, IE's Event object has nothing to tell me, other than type = "error".

There is very little information on the web on using AES-GCM in IE 11.

Please don't tell me to use a different browser. This all works fine (but differently) with Chrome and Firefox. I'm specifically trying to get this to work in IE 11.

What am I missing?

like image 656
James McLachlan Avatar asked Jan 03 '17 17:01

James McLachlan


1 Answers

I found this shim that (vaguely) shows that the tag value goes in the algorithm object and the cipher text alone goes in the third argument. E.g.

let decryptOp = window.msCrypto.subtle.decrypt({
    name: 'AES-GCM',
    iv: iv,
    additionalData: additionalData,
    tag: new Uint8Array(encResult.tag)
    }, key, new Uint8Array(encResult.ciphertext));

Why was this so hard to find? Why are there no blog posts about this feature? Why are MS's docs so short on details?

like image 90
James McLachlan Avatar answered Oct 14 '22 11:10

James McLachlan