6

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?

4

2 回答 2

4

正如评论中所建议的那样,将 IV 更改为 12 而不是 16 并包含其他数据1而不是0修复 Edge 中的问题

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

您对附加数据的评论“//边缘需要,如果附加数据丢失解密失败”真的不需要。additionalData可以是无效的

我在 MSDN 中查找有关加密操作的信息,但没有记录这种行为。所以我觉得WebCrypto的实现还不够成熟,还是有小bug

于 2017-03-22T11:46:10.420 回答
1

在 Edge 41 中,原始代码产生了相同的行为。然而,设置tempAdditionalDatanull解决问题并解密成功。

于 2018-07-27T10:34:35.650 回答