A customer has provided sample code in C# as an encryption spec. My code is in Python 2.7, and I have to make my data match theirs. My data matches an online calculator but not the customer data. To make a demo, I have reduced everything to zero data, keys and IVs.
This is the C#, for .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);
}
Resulting in this output:
Test Encrypt 2, zero data, key and IV: B5 67 D8 36 7C FD F3 7A 89 8F 18 3A 49 83 7A D3
This is 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/
Resulting in:
DC95C078A2408989AD48A21492842087
An online calculator agrees with Python:
Is C# AES-256 known bad, or am I doing something wrong? In each case, I am trying to encrypt a 4 byte cleartext with a 16 byte IV and 32 byte key, all zeroes. Seems like it should be the "lowest common denominator," but various implementations disagree. How do you figure out the truth in this situation? Should I upgrade .Net levels, or import BouncyCastle? Either option takes at least a few hours.