Javascript 解密 aes-gcm 不起作用,但在 Python 中它可以工作

2024-04-01

我想将一个小型 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

像这样的消息:88D5AB4F97515AAFC6B88D2F85DAA7A0E3C0C40D004535C397C9D037AB7DBDA329107615444894A1A0DD7E85F02D496CECD3FF46AF5FB3C9229CFE8F3EE4606AB2E1F409F36AAD2E50900A4396FC6C2E083F373233A69616950758BFC7D63A9E9B6E99E21B2CBC2B934772CA51FD4D69830711CAB1F8CFF25F0A329337CBA51904F0CAED88D61968743C8454BA922EB00038182C22FE316D16F2A9F544D6F75D51A4E92A1C4EF8AB19A2B7FEAA32D0726C0ED80229AE6C0F7621A4209251ACE2B2BC66FF0327A653BB686C756BE033C7A281F1D2A7E1FA31C3983E15F8FD16CC5787E6F517166814146853FF110167419A3CFDA44BE438C96F0E38BF83D9

结果是这样的:0f8006870e0c07e5091b01092f0f00ff88800223090c07e5091b01092f0f00ff888009060100010800ff060000328902020f00161e09060100020800ff060000000002020f00161e09060100010700ff060000000002020f00161b09060100020700ff060000000002020f00161b09060100200700ff12092102020fff162309060100340700ff12000002020fff162309060100480700ff12000002020fff1623090601001f0700ff12000002020ffe162109060100330700ff12000002020ffe162109060100470700ff12000002020ffe1621090601000d0700ff1203e802020ffd16a98558d8881285f5e85e5949158f1dbf4b91e4561312ee738fb5

(这是预期的结果)

我现在尝试使用 Javascript 建立相同的Web加密API https://nodejs.org/api/webcrypto.html。 但我无法让它工作。 这是我的简单代码片段:

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 库不兼容吗? 多谢,

干杯 弗里茨


在这里找到了答案:https://stackoverflow.com/a/49244840/13548905 https://stackoverflow.com/a/49244840/13548905缺少的部分是身份验证标签,实际上是 IV +“00000002”。 添加后,解密成功。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Javascript 解密 aes-gcm 不起作用,但在 Python 中它可以工作 的相关文章

随机推荐

  • SQL:查找表中缺失的层次结构文件夹(路径)

    我有一个包含文件夹路径的表 我需要找到层次结构中这些文件夹之间的所有 间隙 我的意思是 如果表包含这 3 个文件夹 A A B C A B C D E F G 我需要在层次结构中找到以下丢失的文件夹 A B A B C D A B C D
  • Sonar 5.1 问题列表 - 如何按问题类型分组

    我们如何识别当前代码库中项目中最常见的问题类型 我们最近从 Sonar 4 5 升级到 5 1 在4 5中 我们曾经查看特定项目中的问题列表 并且问题按问题类型分组 例如 在一个项目中 规则 使用记录器记录此异常 可能是最常见的关键规则 有
  • 如何检查mysql中的二进制字符串是否为UTF-8?

    我找到了一个 Perl 正则表达式 可以检查字符串是否为 UTF 8 正则表达式来自w3c site http www w3 org International questions qa forms utf 8 en php field m
  • matplotlib 中的等高线图显示不正确的线型

    我正在使用轮廓图在 matplotlib 中绘制一个具有正值和负值的二维矩阵 它应该显示正值的实线和负值的虚线 loc matplotlib ticker MaxNLocator 20 Z psi lvls loc tick values
  • 在SSIS中使用执行进程任务和WinSCP进行SFTP传输

    我有一个User file txt文件放置在 WinSCP 根文件夹 USERDATA 中 我正在尝试将其下载到给定位置C User Local Executable C Program Files x86 WinSCP WinSCP ex
  • React 组件安装两次

    在我的 React Redux ReactRouterV4 应用程序的一小部分中 我有以下组件层次结构 Exhibit Parent ExhibitOne ExhibitTwo ExhibitThree 在 Exhibit 的子级中 还可以
  • 使用远程执行配置程序时,当 instance_count 大于 2 时,Terraform 会卡住

    我正在尝试使用 null resource 通过 Terraform 的远程执行配置程序来配置多个 Windows EC2 实例 terraform v Terraform v0 12 6 provider aws v2 23 0 prov
  • 如何使用 WriteEndElement 检查元素的名称

    我正在写 xmlXmlWriter http msdn microsoft com en gb library system xml xmlwriter aspx 我的代码有很多这样的部分 xml WriteStartElement pay
  • Kafka Consumer Group Id 和消费者重新平衡问题

    我正在使用卡夫卡0 10 0和动物园管理员3 4 6在我的生产服务器中 我有 20 个主题 每个主题大约有 50 个分区 我总共有 100 个消费者 每个消费者订阅了不同的主题和分区 所有消费者都具有相同的 groupId 那么 如果针对特
  • Final 字段和匿名类

    我仍然对有关匿名类和最终字段的解释不满意 有大量问题试图解释明显的问题 但我还没有找到所有问题的答案 假设以下代码 public void method final int i int j final int z 6 final int x
  • 如何在 SearchView/Widget 调用的搜索过程中传递额外的变量?

    我成功地使用操作栏中的搜索小部件来执行以下搜索本指南 http developer android com guide topics search search dialog html 搜索很好 但我想知道如何在搜索中传递其他变量 同一个指
  • PHP 中的类未注册错误

    我们创建了一个 C 类库程序集 并将其设置为 COM 可见 以便能够从 PHP 调用其方法 这曾经运行良好 但现在我们想将其安装在 Windows Server 2008 服务器上 并且不断遇到 类未注册 错误 为了排除任何依赖性问题 我用
  • 有没有一种简单的方法可以用 Pygame 制作和保存动画?

    我制作了一个非常简单的分形生成器 可以打印出每个步骤 我想把它放在我所做的演示中 我用来制作演示的工具显然不支持 pygame 有什么方法可以将其保存为视频吗 最好是动画 gif 等 http visvis googlecode com h
  • 让 CMake 将生成的二进制文件与资产一起放入特定的目录结构中

    我的项目的目录结构基本如下 root src 根 资产 根 库 我目前已将 CMake 设置为编译源代码 编译库 然后通过从根目录调用 make 来链接它们 然后 我必须手动将可执行文件移动到原始资产目 录中以使其运行 因为这是它期望的位置
  • params.getBehaviour() 返回空值

    我正在玩新的 Android 设计库 CollapsingToolbarLayout 工作得很好 但是 我无法将工具栏的默认状态设置为 折叠 我正在尝试实施所示的解决方案here https stackoverflow com questi
  • 无法确定表达式错误的序列化信息

    我得到一个Unable to determine the serialization information for the expression PlaceManager pm gt pm FreePlaces get Item inde
  • 在 Jetty WebAppContext 之间实现 SSO

    我正在开发的 Jetty 9 应用程序会自动扫描一组 JarFiles 中的 web xml 然后以编程方式将包含的 Web 应用程序导入为 WebAppContext 我需要在各个 Web 应用程序之间实现单点登录 如以下 Jetty 6
  • 在Java中编码base64并在C#中解码

    我在java和c 之间遇到了base64问题 我从java urlconnection发送编码字符串到asp net处理程序 我比较两个字符串 在java中从字节数组生成的字符串和在asp net第一次解码中接收的字符串相同 但解码后 c
  • 从套接字到套接字的零分配复制

    假设我们有一个套接字连接 我们称其为c1 我们接受消息的地方 我们还有 N 个其他套接字连接 我们将写入完全相同的消息 为了确定我们希望它写入哪个连接 我们只需要读取其中的前几个字节c1 但是套接字上剩余的字节不需要加载到java堆中 只需
  • Javascript 解密 aes-gcm 不起作用,但在 Python 中它可以工作

    我想将一个小型 python 库移植到 JavaScript 在 Node JS 中运行 我收到一条加密消息 初始化向量和密钥 在 python3 中 这些是导入 from cryptography hazmat primitives ci