.Net 4.7.2 的 AES-256 似乎不正确,是我的用法还是 MS?

问题描述 投票:0回答:1

客户提供了 C# 示例代码作为加密规范。我的代码是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);
    }

产生以下输出:

测试加密2,零数据,密钥和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
...
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) #4) #PKCS7 padding for 4 byte payload
    return PackedStringToHexString(c.encrypt(packedClr))
    #result DC95C078A2408989AD48A21492842087 agrees with http://aes.online-domain-tools.com/

结果:

DC95C078A2408989AD48A21492842087

一个在线计算器与Python一致:

C# AES-256 是否已知不好,或者我做错了什么?在每种情况下,我都尝试使用 16 字节 IV 和 32 字节密钥(全为零)加密 4 字节明文。看起来它应该是“最低公分母”,但各种实现不同意。在这种情况下,你如何找出真相?我应该升级 .Net 级别,还是导入 BouncyCastle?任一选项至少需要几个小时。

aes pycrypto system.security
1个回答
0
投票

在 PKCS#7 填充中,填充字节不为零。相反,如果需要 N 填充字节,则每个字节的值为 N。 (维基百科的示例)。

因此在这种情况下,4 字节的明文需要 12 字节的填充才能形成 128 位的块。每个填充字节的值为十进制 12,即十六进制

0C

填充的明文应该是

000000000C0C0C0C0C0C0C0C0C0C0C0C
。如果您尝试将其作为您展示的在线工具中的明文,使用零密钥和 IV,您会得到与 C# 代码返回相同的
B5 67 D8 36 7C FD F3 7A 89 8F 18 3A 49 83 7A D3

所以在你的Python代码中,填充逻辑应该是这样的:

n_padding = 16 - len(packedClr) % 16
for _ in range(n_padding):
    packedClr += struct.pack("B", n_padding)
© www.soinside.com 2019 - 2024. All rights reserved.