JavaScript解密AES-GCM不起作用,但在Python中起作用
我想将一个小型 python 库移植到 JavaScript,在 Node.JS 中运行。 我收到一条加密消息、初始化向量和密钥。
在 python3 中,这些是导入:
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from binascii import unhexlify
import sys
import string
from Cryptodome.Cipher import AES
解密的工作原理如下:
frame = unhexlify(frame)
encryption_key = unhexlify(str_key)
init_vector = unhexlify(str_iv)
cipher = AES.new(encryption_key, AES.MODE_GCM, nonce=init_vector)
decrypted_msg = cipher.decrypt(frame).hex()
密钥是一个十六进制字符串,如下所示(示例): 36C66639E48A8CA4D6BC8B282A793BBB
IV 是这样的(示例): 4B464D675000000900000023
消息如下: 88D5AB4F97515AAFC6B88D2F85DAA7A0E3C0C40D004535C397C9D037AB7DBDA329107615444894A1A0DD7E85F02D496CECD3FF46AF5FB3C9229CFE8F3EE4 606AB2E1F409F36AAD2E50900A4396FC6C2E083F373233A69616950758BFC7D63 A9E9B6E99E21B2CBC2B934772CA51FD4D69830711CAB1F8CFF25F0A329337CBA5 1904F0CAED88D61968743C8454BA922EB00038182C22FE316D16F2A9F544D6F75 D51A4E92A1C4EF8AB19A2B7FEAA32D0726C0ED80229AE6C0F7621A4209251ACE2 B2BC66FF0327A653BB686C756BE033C7A281F1D2A7E1FA31C3983E15F8FD16CC5787E6F517166814146853FF110167419A3CFDA44BE438C96F0E38BF83D9
结果是这样的: <代码>0f8006870e0c07e5091b01092f0f00ff88800223090c07e5091b01092f0 f00ff888009060100010800ff060000328902020f00161e09060100020800ff06 0000000002020f00161e09060100010700ff060000000002020f00161b0906010 0020700ff060000000002020f00161b09060100200700ff12092102020fff1623 09060100340700ff12000002020fff162309060100480700ff12000002020fff1 623090601001f0700ff12000002020ffe162109060100330700ff12000002020f fe162109060100470700ff12000002020ffe1621090601000d0700ff1203e8020 20ffd16a98558d8881285f5e85e5949158f1dbf4b91e4561312ee738fb5
(这是预期的结果)
我现在尝试使用 WebCrypto API。 但我无法让它工作。 这是我的简单代码片段:
const ba = require('binascii');
const crypto = require('crypto').webcrypto;
const myKey = "36C66639E48A8CA4D6BC8B282A793BBB";
const iv = "4B464D675000000900000023";
const cipherText = "88D5AB4F97515AAFC6B88D2F85DAA7A0E3C0C40D004535C397C9D037AB7DBDA329107615444894A1A0DD7E85F02D496CECD3FF46AF5FB3C9229CFE8F3EE4606AB2E1F409F36AAD2E50900A4396FC6C2E083F373233A69616950758BFC7D63A9E9B6E99E21B2CBC2B934772CA51FD4D69830711CAB1F8CFF25F0A329337CBA51904F0CAED88D61968743C8454BA922EB00038182C22FE316D16F2A9F544D6F75D51A4E92A1C4EF8AB19A2B7FEAA32D0726C0ED80229AE6C0F7621A4209251ACE2B2BC66FF0327A653BB686C756BE033C7A281F1D2A7E1FA31C3983E15F8FD16CC5787E6F517166814146853FF110167419A3CFDA44BE438C96F0E38BF83D9";
function importKey(rawKey) {
console.log('e_key: ', rawKey);
console.log('e_key: ', ba.unhexlify(rawKey));
return crypto.subtle.importKey(
"raw", //can be "jwk" or "raw"
rawKey,
{ //this is the algorithm options
name: "AES-GCM",
length: 256
},
false, //whether the key is extractable (i.e. can be used in exportKey)
["encrypt", "decrypt"] //can "encrypt", "decrypt", "wrapKey", or "unwrapKey"
)
}
function decrypt(data, key, iv) {
console.log(data);
return crypto.subtle.decrypt(
{
name: "AES-GCM",
iv: iv, //The initialization vector you used to encrypt
//additionalData: ArrayBuffer, //The addtionalData you used to encrypt (if any)
//tagLength: 0, //The tagLength you used to encrypt (if any)
},
key, //from generateKey or importKey above
new ArrayBuffer(data) //ArrayBuffer of the data
).then(function(decrypted){
//returns an ArrayBuffer containing the decrypted data
console.log(new Uint8Array(decrypted));
}).catch(function(err){
console.error(err);
});
}
const main = async function() {
var keys = await importKey(myKey)
var decryptedData = await decrypt(cipherText, keys, iv);
console.log(decryptedData);
};
main();
执行时,结果是:
DOMException [OperationError]: The provided data is too small.
at asyncAesGcmCipher (node:internal/crypto/aes:202:30)
at Object.aesCipher (node:internal/crypto/aes:229:28)
at cipherOrWrap (node:internal/crypto/webcrypto:665:10)
at SubtleCrypto.decrypt (node:internal/crypto/webcrypto:680:10)
at decrypt (/Users/fritz/dev/test/simple.js:26:23)
我试图像在 python 中一样保持 1:1,但无法解密该字符串。 我尝试使用 unhexlify 等对所有实体(myKey、iv 和 cipherText)进行操作。但没有成功。
这个 JavaScript AES-GCM 与 python 库不兼容吗? 非常感谢,
干杯 弗里茨
I want to port a small python library to JavaScript, running in Node.JS.
I get an encrypted message, the initialization vector and the key.
In python3 these are the imports:
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from binascii import unhexlify
import sys
import string
from Cryptodome.Cipher import AES
And the decrypt works like this:
frame = unhexlify(frame)
encryption_key = unhexlify(str_key)
init_vector = unhexlify(str_iv)
cipher = AES.new(encryption_key, AES.MODE_GCM, nonce=init_vector)
decrypted_msg = cipher.decrypt(frame).hex()
The key is a hexstring like this (example):36C66639E48A8CA4D6BC8B282A793BBB
IV is this (example):4B464D675000000900000023
Message like this:88D5AB4F97515AAFC6B88D2F85DAA7A0E3C0C40D004535C397C9D037AB7DBDA329107615444894A1A0DD7E85F02D496CECD3FF46AF5FB3C9229CFE8F3EE4606AB2E1F409F36AAD2E50900A4396FC6C2E083F373233A69616950758BFC7D63A9E9B6E99E21B2CBC2B934772CA51FD4D69830711CAB1F8CFF25F0A329337CBA51904F0CAED88D61968743C8454BA922EB00038182C22FE316D16F2A9F544D6F75D51A4E92A1C4EF8AB19A2B7FEAA32D0726C0ED80229AE6C0F7621A4209251ACE2B2BC66FF0327A653BB686C756BE033C7A281F1D2A7E1FA31C3983E15F8FD16CC5787E6F517166814146853FF110167419A3CFDA44BE438C96F0E38BF83D9
It results in this:0f8006870e0c07e5091b01092f0f00ff88800223090c07e5091b01092f0f00ff888009060100010800ff060000328902020f00161e09060100020800ff060000000002020f00161e09060100010700ff060000000002020f00161b09060100020700ff060000000002020f00161b09060100200700ff12092102020fff162309060100340700ff12000002020fff162309060100480700ff12000002020fff1623090601001f0700ff12000002020ffe162109060100330700ff12000002020ffe162109060100470700ff12000002020ffe1621090601000d0700ff1203e802020ffd16a98558d8881285f5e85e5949158f1dbf4b91e4561312ee738fb5
(which is the expected outcome)
I've now tried to establish the same in Javascript using the WebCrypto API.
But I can't manage it to work.
Here's my simple code snippet:
const ba = require('binascii');
const crypto = require('crypto').webcrypto;
const myKey = "36C66639E48A8CA4D6BC8B282A793BBB";
const iv = "4B464D675000000900000023";
const cipherText = "88D5AB4F97515AAFC6B88D2F85DAA7A0E3C0C40D004535C397C9D037AB7DBDA329107615444894A1A0DD7E85F02D496CECD3FF46AF5FB3C9229CFE8F3EE4606AB2E1F409F36AAD2E50900A4396FC6C2E083F373233A69616950758BFC7D63A9E9B6E99E21B2CBC2B934772CA51FD4D69830711CAB1F8CFF25F0A329337CBA51904F0CAED88D61968743C8454BA922EB00038182C22FE316D16F2A9F544D6F75D51A4E92A1C4EF8AB19A2B7FEAA32D0726C0ED80229AE6C0F7621A4209251ACE2B2BC66FF0327A653BB686C756BE033C7A281F1D2A7E1FA31C3983E15F8FD16CC5787E6F517166814146853FF110167419A3CFDA44BE438C96F0E38BF83D9";
function importKey(rawKey) {
console.log('e_key: ', rawKey);
console.log('e_key: ', ba.unhexlify(rawKey));
return crypto.subtle.importKey(
"raw", //can be "jwk" or "raw"
rawKey,
{ //this is the algorithm options
name: "AES-GCM",
length: 256
},
false, //whether the key is extractable (i.e. can be used in exportKey)
["encrypt", "decrypt"] //can "encrypt", "decrypt", "wrapKey", or "unwrapKey"
)
}
function decrypt(data, key, iv) {
console.log(data);
return crypto.subtle.decrypt(
{
name: "AES-GCM",
iv: iv, //The initialization vector you used to encrypt
//additionalData: ArrayBuffer, //The addtionalData you used to encrypt (if any)
//tagLength: 0, //The tagLength you used to encrypt (if any)
},
key, //from generateKey or importKey above
new ArrayBuffer(data) //ArrayBuffer of the data
).then(function(decrypted){
//returns an ArrayBuffer containing the decrypted data
console.log(new Uint8Array(decrypted));
}).catch(function(err){
console.error(err);
});
}
const main = async function() {
var keys = await importKey(myKey)
var decryptedData = await decrypt(cipherText, keys, iv);
console.log(decryptedData);
};
main();
When executed, it results in:
DOMException [OperationError]: The provided data is too small.
at asyncAesGcmCipher (node:internal/crypto/aes:202:30)
at Object.aesCipher (node:internal/crypto/aes:229:28)
at cipherOrWrap (node:internal/crypto/webcrypto:665:10)
at SubtleCrypto.decrypt (node:internal/crypto/webcrypto:680:10)
at decrypt (/Users/fritz/dev/test/simple.js:26:23)
I tried to keep things 1:1 as in python, but can't decrypt this string.
I tried for all entities (myKey, iv and cipherText) with and with unhexlify, etc. No luck.
Is this JavaScript AES-GCM not compatible with the python library?
Thanks a lot,
Cheers
Fritz
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在这里找到答案:
https://stackoverflow.com/a/49244840/13548905
缺失的部分是身份验证标签,实际上是IV +“ 00000002”。
添加时,解密起作用。
Found the answer here:
https://stackoverflow.com/a/49244840/13548905
the missing part was the authentication tag, which in fact is IV + "00000002".
When added, decrypt worked.