Web Crypto API using Microsoft Edge (38.14393.0.0)
我在 Chrome(自从第一个 Web Crypto 支持以来)、Firefox(自从第一个 Web Crypto 支持)甚至 Safari TP 上都成功使用了 Web Crypto API (https://www.w3.org/TR/WebCryptoAPI/) (10.2) 在 WebCrypto Liner 的支持下,WebCrypto API (https://github.com/PeculiarVentures/webcrypto-liner) 的 pollyfill。
现在我想使用 Microsoft Edge 测试我们的代码。但是加密和解密示例 ArrayBuffer 已经失败。这里的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | 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); }); } |
此代码在 Edge 上的解密阶段(代码中的第 3 步)失败,而在 Chrome、Firefox 甚至 Safari 上运行良好。有线部分,decryptedDataPromise 被异常拒绝,但返回的数据看起来根本不像异常:
1 | [object Object] {additionalData: Uint8Array {...}, iv: Uint8Array {...}, name:"AES-GCM", tagLength: 128} |
有人知道为什么这在 Microsoft Edge 上会失败吗?
正如评论中所建议的,将 IV 更改为 12 而不是 16 并且附加数据以包含
中的问题
1 2 | var tempIv = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]); var tempAdditionalData = new Uint8Array(1); |
您对附加数据的评论"// 边缘需要,如果附加数据丢失解密失败"真的不需要。
我在 MSDN 中查找有关加密操作的信息,但没有记录此行为。所以我觉得WebCrypto的实现还不够成熟,还是有小bug
在 Edge 41 中,原始代码产生了相同的行为。
但是,将