Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web Crypto API using Microsoft Edge (38.14393.0.0)

I am using the Web Crypto API (https://www.w3.org/TR/WebCryptoAPI/) successfully on Chrome (since first Web Crypto support), Firefox (since first Web Crypto support) and even on Safari TP (10.2) with support of a WebCrypto Liner a pollyfill for WebCrypto API (https://github.com/PeculiarVentures/webcrypto-liner).

Now I want to test our code using Microsoft Edge. But encrypting and decrypting a sample ArrayBuffer already fails. Here the code:

var crypto = window.crypto;
if (crypto.subtle) {
    var aesGcmKey = null;
    // always create a new, random iv in production systems!!!
    var tempIv = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
    // needed for edge, if additional data missing decrypting is failing
    var tempAdditionalData = new Uint8Array(0);
    var dataToEncrypt = new Uint8Array([1, 2, 3, 4, 5]);

    // 1.) generate key
    var generateKeyPromise = crypto.subtle.generateKey(
        {name: "AES-GCM", length: 256}, true, ["encrypt", "decrypt"]
    );
    generateKeyPromise.then(function (tempKey) {
        aesGcmKey = tempKey;
        // 2.) start encryption with this key
        var encryptedDataPromise = crypto.subtle.encrypt(
            {name: "AES-GCM", iv: tempIv, additionalData: tempAdditionalData, tagLength: 128},
            aesGcmKey,
            dataToEncrypt
        );
        encryptedDataPromise.then(function (encryptedData) {
            // 3.) decrypt using same key
            var decryptedDataPromise = crypto.subtle.decrypt(
                {name: "AES-GCM", iv: tempIv, additionalData: tempAdditionalData, tagLength: 128},
                aesGcmKey,
                encryptedData
            );
            decryptedDataPromise.then(function (decryptedData) {
                // 4.) compare decrypted array buffer and inital data
                console.log('data decrypted!');
                console.log(decryptedData);
            });
            decryptedDataPromise.catch(function (error) {
                console.log('decrypting sample data failed');
                console.log(error);
            });
        });
        // if 2.) is failing
        encryptedDataPromise.catch(function (error) {
            console.log('encrypting sample data failed');
            console.log(error);
        });
    });
    // if 1.) is failing
    generateKeyPromise.catch(function (error) {
        console.log('creating aec gcm key failed');
        console.log(error);
    });
}

This code is failing in the decrypting phase (step 3. in the code) on Edge, while its working fine on Chrome, Firefox and even Safari. The wired part it that the decryptedDataPromise is rejected with an exception but the returned data doesnt look like an exception at all:

[object Object] {additionalData: Uint8Array {...}, iv: Uint8Array {...}, name: "AES-GCM", tagLength: 128}

Does anybody have a clue why this fails on Microsoft Edge?

like image 400
developer346 Avatar asked Mar 21 '17 16:03

developer346


People also ask

Does Microsoft Edge support the Web Cryptography API?

This document describes the level of support provided by Microsoft Edge for the Web Cryptography API specification. This page and associated content may be updated frequently. We recommend you subscribe to the RSS feed to receive update notifications.

What is web Crypto API?

Web Crypto API The Web Crypto API is an interface allowing a script to use cryptographic primitives in order to build systems using cryptography.

What is the Microsoft base cryptographic Provider (CSP)?

The Microsoft Base Cryptographic Provider is the initial cryptographic service provider (CSP) provider, and is distributed with CryptoAPI versions 1.0 and 2.0. It is a general-purpose provider that supports digital signatures and data encryption. Obtains the private key for a certificate. Data signing does not protect the data.

What is next generation cryptography API (CNG)?

Purpose Cryptography API: Next Generation (CNG) is the long-term replacement for the CryptoAPI. CNG is designed to be extensible at many levels and cryptography agnostic in behavior.


2 Answers

As suggested in comments, changing IV to size 12 instead of 16 and additional data to contain 1 instead of 0 fix the issue in Edge

var tempIv = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
var tempAdditionalData = new Uint8Array(1);

Your comment about additional data "// needed for edge, if additional data missing decrypting is failing" is really not needed. additionalData can be void

I was looking in MSDN about encrypt operation, but it is not documented this behaviour. So I think the implementation of WebCrypto is not mature enough and still there are small bugs

like image 51
pedrofb Avatar answered Sep 18 '22 08:09

pedrofb


In Edge 41 the original code produces the same behavior. Setting tempAdditionalData to null however solves the problem and decrypt succeeds.

like image 36
sw0rdf1sh Avatar answered Sep 21 '22 08:09

sw0rdf1sh