Search code examples
c#encryptioncryptographyaes

Why does AES decryptor always returns 16 zeros (in 16 bytes)?


My goal is to get a very simple block cipher, that is, the Core of AES. It must take a key and a block and return a block. The decryptor should take the key and the block an return the original block.

I have been testing with the following key (in hex)

AA000000000000000000000000000000

and the following plain text

AA000000000000000000000000000000

(again in hex, and yes, the same as the key)

The result should be

814827A94525FF24B90F20BEC065866D

and indeed it is. (You can verify here that that should be the result at http://www.cryptogrium.com/aes-encryption-online-ecb.html with this as input and selecting AES-128).

But the decryptor always returns

00000000000000000000000000000000

(Only zeros).

What I'm I doing wrong in the following implementation? This implementation is only for educational purposes. That is why I used ECB mode and why I'm expecting always the same encryption.

namespace CryptographyCSharp
{
using System;
using System.Security.Cryptography;

public class MyAes
{
    public static string EncryptStringToBytes_Aes(string msg_hex, string key_hex)
    {
        if (msg_hex == null)
            throw new ArgumentNullException("msg_hex");
        if (key_hex == null)
            throw new ArgumentNullException("key_hex");

        byte[] output = new byte[16];
        msg_hex = msg_hex.PadRight(32, '0');
        key_hex = key_hex.PadRight(32, '0');
        using (var aes = Aes.Create("AES"))
        {
            
            aes.BlockSize = 128;
            aes.KeySize = 128;
            aes.Mode = CipherMode.ECB;
            if (!aes.ValidKeySize(128))
            {
                throw new Exception();
            }

            ICryptoTransform encryptor = aes.CreateEncryptor(key_hex.hex2bytes(), null);
            encryptor.TransformBlock(msg_hex.hex2bytes(), 0, 16, output, 0);
            encryptor.Dispose();
        }

        return output.tohex();
    }

    public static string DecryptStringFromBytes_Aes(string hex_ct, string key_hex)
    {
        if (hex_ct == null)
            throw new ArgumentNullException("cipherText");
        if (key_hex == null)
            throw new ArgumentNullException("Key");

        hex_ct = hex_ct.PadRight(32, '0');
        key_hex = key_hex.PadRight(32, '0');
        string plaintext = null;

        using (Aes aes = Aes.Create("AES"))
        {
            aes.BlockSize = 128;
            aes.KeySize = 128;
            aes.Mode = CipherMode.ECB;
            if (!aes.ValidKeySize(128))
            {
                throw new Exception();
            }

            ICryptoTransform decryptor = aes.CreateDecryptor(key_hex.hex2bytes(), null);
            var output = new byte[16];
            decryptor.TransformBlock(hex_ct.hex2bytes(), 0, 16, output, 0);
            plaintext = output.tohex();
        }

        return plaintext;
    }
}
}

I have used some extension methods that transform hex to bytes and viceversa (that is string.hex2bytes and bytes[].tohex). I can provide them if you need them.


Solution

  • Add aes.Padding = PaddingMode.None; in decryption method.