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

.NET 4.2.7 AES-256加密结果与Python不符,求问题排查方案

AES-256加密:.NET与Python实现结果不一致问题排查

问题背景

客户提供基于.NET 4.2.7的C# AES-256加密代码作为规范,用Python 2.7实现对应逻辑后,加密结果无法匹配。为排查问题,将明文、密钥、IV均设置为全零值,得到两组不同输出。


C#(.NET 4.2.7)代码及输出

private static void TestEncrypt2()
{
    byte[] bytesToEncrypt = new byte[] { 0x00, 0x00, 0x00, 0x00 };

    byte[] encrypted = null;

    using (var cryptoService = Aes.Create())
    {
        cryptoService.Key = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
        cryptoService.IV =  new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

        using (ICryptoTransform encryptor = cryptoService.CreateEncryptor(cryptoService.Key, cryptoService.IV))
        {
            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    csEncrypt.Write(bytesToEncrypt, 0, bytesToEncrypt.Length);
                    csEncrypt.FlushFinalBlock();
                    encrypted = msEncrypt.ToArray();
                }
            }
        }
    }
    DumpByteArray(encrypted);
}

输出:

Test Encrypt 2, zero data, key and IV:
B5 67 D8 36 7C FD F3 7A
89 8F 18 3A 49 83 7A D3


Python 2.7代码及输出

from Crypto.Cipher import AES
import struct

def ByteListToPackedString(byte_list):
    return ''.join(chr(b) for b in byte_list)

def HexStringToByteList(hex_str):
    return [int(hex_str[i:i+2], 16) for i in range(0, len(hex_str), 2)]

def PackedStringToHexString(packed_str):
    return ''.join('%02X' % ord(c) for c in packed_str)

def SREncrypt0():
    packedIv = ByteListToPackedString([0]*16)
    packedKey = ByteListToPackedString([0]*32)
    c = AES.new(packedKey, AES.MODE_CBC, packedIv)
    packedClr = ByteListToPackedString(HexStringToByteList("00000000"))
    while 0 != (len(packedClr) % 16):
        packedClr += struct.pack("B", 0) # 补零填充
    return PackedStringToHexString(c.encrypt(packedClr))

# 输出结果:DC95C078A2408989AD48A21492842087

输出:

DC95C078A2408989AD48A21492842087

Python结果与标准加密工具输出一致。


问题原因及解决方案

1. 核心原因:填充模式不匹配

.NET的Aes类默认使用PKCS#7填充,而你的Python代码采用补零填充,这是导致结果差异的根本原因:

  • 对于4字节明文,PKCS#7会填充12个0x0C(填充字节的值等于填充长度);
  • 补零填充则填充12个0x00。

2. 统一填充模式的两种方案

方案一:修改Python代码使用PKCS#7填充

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad

def ByteListToPackedString(byte_list):
    return ''.join(chr(b) for b in byte_list)

def HexStringToByteList(hex_str):
    return [int(hex_str[i:i+2], 16) for i in range(0, len(hex_str), 2)]

def PackedStringToHexString(packed_str):
    return ''.join('%02X' % ord(c) for c in packed_str)

def SREncrypt0():
    packedIv = ByteListToPackedString([0]*16)
    packedKey = ByteListToPackedString([0]*32)
    c = AES.new(packedKey, AES.MODE_CBC, packedIv)
    packedClr = ByteListToPackedString(HexStringToByteList("00000000"))
    # 替换为PKCS#7填充
    padded_clr = pad(packedClr, AES.block_size, style='pkcs7')
    return PackedStringToHexString(c.encrypt(padded_clr))

# 输出将与C#结果一致:B567D8367CFDF37A898F183A49837AD3

方案二:修改C#代码使用补零填充

在C#代码中添加一行设置填充模式:

cryptoService.Padding = PaddingMode.Zeros;

修改后C#代码的输出将和Python补零填充的结果完全匹配。

3. 关于.NET版本与BouncyCastle

不需要升级.NET版本,也不需要引入BouncyCastle库。问题并非.NET的AES实现存在缺陷,仅为填充模式的配置差异。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 14:29:54