Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# UTF8 Encoding issue with AES Encryption

I'm creating a TCP based chat client. I'm trying to Encrypt some of the data with AES (more security) I have a AES encryption class and it uses UTF-8 by default as the out going and incoming Encoding type. But for some reason when i pass the information over the TCPClient (using UTF-8) and get it the other side it is throwing an error:

`System.Security.Cryptography.CryptographicException: Length of the data to decrypt is invalid.
   at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
   at System.Security.Cryptography.CryptoStream.FlushFinalBlock()`

So I recreated the problem without using the TCP client, just taking the AES encrypted data and putting it through a UTF-8 Encoding system that gets the string of the byte array then re-gets the byte array all using UTF-8 (basically the same thing as what happens over the network (without the string))

This method works:

        string dataToEncrypt = "Hello World";
        byte[] key = Encryption.AesEncryption.GenerateKey(32);
        byte[] iv = Encryption.AesEncryption.GenerateKey(16);

        byte[] encrypted = Encryption.AesEncryption.EncryptString(dataToEncrypt, key, iv);

        string decrypted = Encryption.AesEncryption.DecryptedBytes(encrypted, key, iv);

The method doesn't work (throws the error from above)

        Encoding encoding = Encoding.UTF8;

        string dataToEncrypt = "Hello World";
        byte[] key = Encryption.AesEncryption.GenerateKey(32);
        byte[] iv = Encryption.AesEncryption.GenerateKey(16);

        byte[] encrypted = Encryption.AesEncryption.EncryptString(dataToEncrypt, key, iv);

        string encstring = encoding.GetString(encrypted);

        byte[] utf8encrypted = encoding.GetBytes(encstring);

        string decrypted = Encryption.AesEncryption.DecryptedBytes(utf8encrypted, key, iv);

What am i doing wrong?

This is my Encryption Class:

public sealed class AesEncryption
{
    private byte[] Key;

    public Encoding Encoder = Encoding.UTF8;

    public AesEncryption(byte[] key)
    {
        Key = key;
    }

    public byte[] Encrypt(string text, byte[] iv)
    {
        var bytes = Encoder.GetBytes(text);
        var rm = new RijndaelManaged();
        var encrypter = rm.CreateEncryptor(Key, iv);
        var ms = new MemoryStream();
        var cs = new CryptoStream(ms, encrypter, CryptoStreamMode.Write);
        cs.Write(bytes, 0, bytes.Length);
        cs.FlushFinalBlock();
        var output = ms.ToArray();
        cs.Close();
        ms.Close();
        return output;
    }

    public string Decrypt(byte[] encrypted, byte[] iv)
    {
        var ms = new MemoryStream();
        var cs = new CryptoStream(ms,
            new RijndaelManaged().CreateDecryptor(Key, iv),
            CryptoStreamMode.Write);
        cs.Write(encrypted, 0, encrypted.Length);
        cs.FlushFinalBlock();
        var output = ms.ToArray();
        cs.Close();
        ms.Close();
        return Encoder.GetString(output);
    }

    public static byte[] EncryptString(string text, byte[] key, byte[] iv)
    {
        var ec = new AesEncryption(key);
        return ec.Encrypt(text, iv);
    }

    public static string DecryptedBytes(byte[] encrypted, byte[] key, byte[] iv)
    {
        var ec = new AesEncryption(key);
        return ec.Decrypt(encrypted, iv);
    }

    public static byte[] GenerateKey(int length)
    {
        Random rnd = new Random();

        var chars = "1!2@3#4$5%6^7&8*9(0)-_=+qQwWeErRtTyYuUiIoOpP[{]}\\|aAsSdDfFgGhHjJkKlL;:'\"zZxXcCvVbBnNmM,<.>/?".ToCharArray();

        string randomizedKey = "";

        for (int i = 0; i < length; i++)
        {
            randomizedKey += chars[rnd.Next(0, chars.Length)];
        }
        return randomizedKey.ToByteArray();
    }
}
like image 970
Mr. Sir. Alec Jr. Avatar asked Oct 19 '22 23:10

Mr. Sir. Alec Jr.


1 Answers

UTF-8 does not perfectly represent the bytes. The short and simple answer is: Transmit bytes, not a UTF-8 string. If you must have a string, encode it in Base64.

like image 54
mcmonkey4eva Avatar answered Oct 22 '22 12:10

mcmonkey4eva