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

AES-256 GCM解密报错MAC check failed问题求助

解决AES-256 GCM解密MAC校验失败及乱码问题

MAC校验失败(ValueError: MAC check failed)的核心原因及排查方向

  • 密钥长度不匹配:AES-256要求密钥必须是32字节(256位),如果用了16字节(AES-128)或24字节(AES-192)的密钥,会直接导致校验失败。
  • IV/Nonce错误:GCM模式的IV(Nonce)必须与加密时完全一致,且通常为12字节(GCM推荐长度)。如果JSON中的IV是Base64/十六进制编码,必须正确解码为bytes,不能用字符串直接传入。
  • Tag值错误:Tag是GCM的完整性校验值,必须和加密时生成的完全一致。注意JSON中的Tag是否经过编码(如Base64),解码错误会直接触发校验失败。
  • 附加数据(AD)不一致:如果加密过程中使用了附加数据(Authenticated Data),解密时必须传入完全相同的附加数据,否则MAC校验不通过。

直接使用decrypt方法出现乱码的原因

GCM模式的decrypt方法不会自动校验Tag,跳过校验后输出的内容可能是被篡改的明文,或者因为密钥/IV参数错误导致解密出的字节本身就是无效的,最终解码为乱码。必须使用decrypt_and_verify方法才能同时完成解密和完整性校验。

正确的解密代码示例

假设JSON中的content、iv、tag均为Base64编码(如果是十六进制,替换为bytes.fromhex()):

from Crypto.Cipher import AES
import base64
import json

def decrypt_aes256_gcm(encrypted_json_str, aes_key):
    # 解析JSON数据
    encrypted_data = json.loads(encrypted_json_str)
    
    # 解码加密字段为bytes类型
    ciphertext = base64.b64decode(encrypted_data["content"])
    iv = base64.b64decode(encrypted_data["iv"])
    tag = base64.b64decode(encrypted_data["tag"])
    
    # 验证密钥长度合法性
    if len(aes_key) != 32:
        raise ValueError("AES-256 requires a 32-byte key")
    
    # 初始化GCM密码器
    cipher = AES.new(aes_key, AES.MODE_GCM, nonce=iv)
    
    # 若加密时使用了附加数据,需先调用update传入对应数据
    # cipher.update(b"your_authenticated_data_here")
    
    try:
        # 解密并校验Tag
        plaintext_bytes = cipher.decrypt_and_verify(ciphertext, tag)
        # 转换为字符串(若加密时未做填充,无需unpad)
        return plaintext_bytes.decode("utf-8")
    except ValueError as e:
        raise RuntimeError(f"Decryption failed: {str(e)}")

# 使用示例
encrypted_msg = '{"content": "abc123...", "iv": "def456...", "tag": "ghi789..."}'
# 32字节的AES密钥,注意必须是bytes类型
aes_256_key = b"your_32_byte_secret_key_12345678"

try:
    plaintext = decrypt_aes256_gcm(encrypted_msg, aes_256_key)
    print(plaintext)
except Exception as e:
    print(e)

额外排查要点

  • 确认加密端是否对明文做了填充:如果加密时用了PKCS7填充,解密后需要调用unpad(plaintext_bytes, AES.block_size)去除填充。
  • 检查字符编码:明文通常是UTF-8编码,若加密端用了其他编码(如GBK),需对应调整解码方式。
  • 避免密钥/IV的字符串编码错误:不要直接用str(key)转换,确保密钥是原生bytes类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 17:34:53