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