You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AES-256-GCM跨语言解密问题:Python解码NodeJS加密数据报错

解决NodeJS AES-GCM加密数据的Python解密问题

问题现象

使用Python解密NodeJS加密的AES-GCM数据时,执行decrypted.decode('utf-8')触发解码错误:

Error: 'utf-8' codec can't decode byte 0xc8 in position 0: invalid continuation byte

原代码对比

Python 解密代码(错误版本)

import base64
from Crypto.Cipher import AES

args = {
    "content": "725cd5204cf64987a39a6622884527e0",
    "iv": "e6174b11cd2a18fc",
    "tag": {
        "data": [26, 91, 205, 206, 134, 22, 167, 101, 110, 27, 155, 100, 41, 99, 34, 135],
        "type": "Buffer"
    },
    "key": "SqqUUMnwEVUCBYT7p/0Zfz4Cq2eazHqQ"
}

def decrypt_auth_tag(args):
    try:
        key = args["key"]
        content = bytes.fromhex(args["content"])
        iv = bytes.fromhex(args["iv"])
        tag = bytes(args["tag"]["data"])
        
        cipher = AES.new(key.encode('utf-8'), AES.MODE_GCM, nonce=iv)
        cipher.update(tag)  # 错误核心
        decrypted = cipher.decrypt(content)
        return decrypted.decode('utf-8')
    except Exception as e:
        print("Error:", e)

print(decrypt_auth_tag(args))

NodeJS 解密代码(正常工作版本)

const crypto = require('crypto');

let args = {
    "content": "725cd5204cf64987a39a6622884527e0",
    "iv": "e6174b11cd2a18fc",
    "tag":
    {
        "data": [26, 91, 205, 206, 134, 22, 167, 101, 110, 27, 155, 100, 41, 99, 34, 135],
        "type": "Buffer"
    }
}
// Decrypts the data using a key, iv, and auth tag
function decryptAuthTag(args) {
    try {
        const key = "SqqUUMnwEVUCBYT7p/0Zfz4Cq2eazHqQ";
        const encrypted = {
            content: args.content,
            iv: args.iv,
            tag: args.tag
        };

        const alg = 'aes-256-gcm';
        const decipher = crypto.createDecipheriv(alg, key, encrypted.iv);
        decipher.setAuthTag(Buffer.from(encrypted.tag));
        let dec = decipher.update(encrypted.content, 'hex', 'utf8');
        dec += decipher.final('utf8');
        return dec;
    } catch (error) {
        return "ERROR"
    }
}

console.log(decryptAuthTag(args))

错误原因与修正方案

核心错误点

Python代码中错误地将**认证标签(tag)当作附加认证数据(AAD)**调用cipher.update(tag),但NodeJS里是通过setAuthTag()设置认证标签,用于解密后的完整性校验。

修正后的Python代码

import base64
from Crypto.Cipher import AES

args = {
    "content": "725cd5204cf64987a39a6622884527e0",
    "iv": "e6174b11cd2a18fc",
    "tag": {
        "data": [26, 91, 205, 206, 134, 22, 167, 101, 110, 27, 155, 100, 41, 99, 34, 135],
        "type": "Buffer"
    },
    "key": "SqqUUMnwEVUCBYT7p/0Zfz4Cq2eazHqQ"
}

def decrypt_auth_tag(args):
    try:
        key = args["key"]
        content = bytes.fromhex(args["content"])
        iv = bytes.fromhex(args["iv"])
        tag = bytes(args["tag"]["data"])
        
        cipher = AES.new(key.encode('utf-8'), AES.MODE_GCM, nonce=iv)
        # 移除错误的cipher.update(tag)
        decrypted = cipher.decrypt(content)
        # 解密后验证认证标签
        cipher.verify(tag)
        return decrypted.decode('utf-8')
    except Exception as e:
        print("Error:", e)

print(decrypt_auth_tag(args))

关键修改说明

  1. 移除cipher.update(tag):该方法用于处理附加认证数据(AAD),而非认证标签,NodeJS代码中并未使用AAD,因此不需要这一步。
  2. 添加cipher.verify(tag):解密完成后调用此方法验证认证标签的完整性,这与NodeJS的setAuthTag()逻辑完全对应。

运行修正后的代码即可得到与NodeJS一致的解密结果。

内容的提问来源于stack exchange,提问作者Melque Lima

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 18:24:58