Web 加密 API 使用 Microsoft Edge (38.14393.0.0)
Web Crypto API using Microsoft Edge (38.14393.0.0)
我正在使用 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)。
现在我想使用 Microsoft Edge 测试我们的代码。但是加密和解密示例 ArrayBuffer 已经失败。这里的代码:
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 上运行良好。有线部分是解密的 DataPromise 被异常拒绝,但返回的数据看起来根本不像异常:
[object Object] {additionalData: Uint8Array {...}, iv: Uint8Array {...}, name: "AES-GCM", tagLength: 128}
有人知道为什么这在 Microsoft Edge 上失败了吗?
如评论中所建议,将 IV 的大小从 16 改为 12 并将附加数据包含 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 中查找有关 encrypt 操作的信息,但没有记录此行为。所以我觉得WebCrypto的实现还不够成熟,还有小bug
在 Edge 41 中,原始代码产生相同的行为。
但是,将 tempAdditionalData
设置为 null
即可解决问题并解密成功。
我正在使用 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)。
现在我想使用 Microsoft Edge 测试我们的代码。但是加密和解密示例 ArrayBuffer 已经失败。这里的代码:
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 上运行良好。有线部分是解密的 DataPromise 被异常拒绝,但返回的数据看起来根本不像异常:
[object Object] {additionalData: Uint8Array {...}, iv: Uint8Array {...}, name: "AES-GCM", tagLength: 128}
有人知道为什么这在 Microsoft Edge 上失败了吗?
如评论中所建议,将 IV 的大小从 16 改为 12 并将附加数据包含 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 中查找有关 encrypt 操作的信息,但没有记录此行为。所以我觉得WebCrypto的实现还不够成熟,还有小bug
在 Edge 41 中,原始代码产生相同的行为。
但是,将 tempAdditionalData
设置为 null
即可解决问题并解密成功。