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?
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.
Web Crypto API The Web Crypto API is an interface allowing a script to use cryptographic primitives in order to build systems using cryptography.
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.
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.
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
In Edge 41 the original code produces the same behavior.
Setting tempAdditionalData
to null
however solves the problem and decrypt succeeds.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With