AesCryptoServiceProvider throws Cryptographic exception

322 views Asked by At

I am doing some project for school. I am having server client communication with TcpClient and TcpListener. At the begining I create AES key on server, and then send it to client using RSA. I have no problems here. However, when I try to encrypt string on client and then encrpyt it on server I get an exception.

  1. Padding is invalid and cannot be removed

Server code:

Byte[] bytes = new Byte[1024];
String data = null;
clientStream.Read(bytes, 0, bytes.Length); // preberemo iz streama
//Array.Clear(bytes, 0, bytes.Length);
// string temp = Encoding.UTF8.GetString(bytes11);
//temp = temp.Replace("\0", "");
//yte[] bytes = Encoding.UTF8.GetBytes(temp);
using (MemoryStream msEncrypt = new MemoryStream())
{

    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, aes.CreateDecryptor(aes.Key,aes.IV), CryptoStreamMode.Write))
    {

        //StreamWriter swEncrypt = new StreamWriter(csEncrypt);

        csEncrypt.Write(bytes, 0, bytes.Length);


    }
    byte[] encrypted = msEncrypt.ToArray();
    string enc = Encoding.UTF8.GetString(encrypted, 0, encrypted.Length);
}

Client code:

byte[] messg = Encoding.UTF8.GetBytes(messig);
// dobimo client stream
string enc = null;
using (MemoryStream msEncrypt = new MemoryStream())
{


    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, aes.CreateEncryptor(aes.Key, aes.IV), CryptoStreamMode.Write))
    {

        csEncrypt.Write(messg,0,messg.Length);
    }
    byte[] encrypted = msEncrypt.ToArray();
    enc = Encoding.UTF8.GetString(encrypted, 0, encrypted.Length);
}
byte[] data = new byte[1024];
data = Encoding.UTF8.GetBytes(enc);
//CryptoStream CryptStream = new CryptoStream(stream,aes.CreateEncryptor(aes.Key, aes.IV),CryptoStreamMode.Write);


stream.Write(data, 0, data.Length); // pošljem sporočilo

I get exception on server when trying to use msEncrypt.ToArray();

However If I dinamically allocate Byte[], or I remove all the null values, I get an exception saying "the input data is not a complete block".

2

There are 2 answers

1
n32303 On BEST ANSWER

I have solved this using:

aes.Padding = PaddingMode.Zeros;
2
Maarten Bodewes On

The problem is likely Encoding.UTF8.GetString(encrypted, 0, encrypted.Length);. That means the code treats bytes that can have any value as a text encoding. This means that if the bytes do not represent valid text that they will either change value (e.g. be substituted with question marks) or left out all together.

It is required to use base 64 encoding to treat the ciphertext as actual text. In this modern day and age, ciphertext is always binary (usually grouped in bytes).


Note that using PaddingMode.Zeros does not solve the problem. There may be information removed from the ciphertext if UTF-8 decoding is used. PaddingMode.Zeros only removes the exception, it doesn't solve the underlying problem of information loss.