C #: AES error: padding is invalid and cannot be deleted. The same key and all help

I am new to C #, so please be patient with me. I know that this question has been asked many times, but I could not find the answer to my problem.

I save some data and before writing it to a file, I convert it to a binary file and save it in an array, which I encrypt, and then write to a file. I encrypt data in chunks (32 bytes). In the same way, I read data in pieces of 32 bytes, and then decrypts this data, and then it should be repeated until the end of the file. But when it comes to decryption, the following error occurs:

Filling is invalid and cannot be deleted.

I use the same key and iv (hardcoded until I get it working)

Here is my encryption code that works without problems:

//result byte[] data = new byte[32]; //setup encryption (AES) SymmetricAlgorithm aes = Aes.Create(); byte[] key = { 145, 12, 32, 245, 98, 132, 98, 214, 6, 77, 131, 44, 221, 3, 9,50}; byte[] iv = { 15, 122, 132, 5, 93, 198, 44, 31, 9, 39, 241, 49, 250, 188, 80, 7 }; ICryptoTransform encryptor = aes.CreateEncryptor(key, iv); FileStream fStream = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read, 1024, false); //prepare data to write (byte array 'data') ... //encrypt MemoryStream m = new MemoryStream(); using (Stream c = new CryptoStream(m, encryptor, CryptoStreamMode.Write)) c.Write(data, 0, data.Length); data = m.ToArray(); fStream.Write(data, 0, data.Length); 

And here is my decryption code:

 FileStream fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, false); //setup encryption (AES) SymmetricAlgorithm aes = Aes.Create(); byte[] key = { 145, 12, 32, 245, 98, 132, 98, 214, 6, 77, 131, 44, 221, 3, 9, 50 }; byte[] iv = { 15, 122, 132, 5, 93, 198, 44, 31, 9, 39, 241, 49, 250, 188, 80, 7 }; ICryptoTransform decryptor = aes.CreateDecryptor(key, iv); //result byte[] data = new byte[32]; //loop for reading the whole file ... int len = fStream.Read(data, 0, 32); //decrypt MemoryStream m = new MemoryStream(); using (Stream c = new CryptoStream(m, decryptor, CryptoStreamMode.Write)) c.Write(data, 0, data.Length); //The exception is thrown in this line data = m.ToArray(); //using the decrypted data and then looping back to reading and decrypting... 

I tried everything I could come up with (this is not because I am very new to cryptography), I searched everywhere and I could not find a solution to my problem. I also helped myself with the C # book in a nutshell.

If anyone has ideas on why this might happen, I will be very grateful because I have no ideas.

Thanks for your time and answers.

EDIT: It seems that the size of the encrypted data is 48 bytes (12 bytes larger than the original). Why is this so? I thought that it only adds bytes if they are not a multiple of the block size (16 bytes, my data is 32 bytes). Is there always always more data and with a constant increase (I need to know that for proper reading and decryption).

Note. I cannot directly use other streams, because I need to have control over the output format, and I believe that it is also safer and faster in memory encryption.

+6
c # padding aes
source share
3 answers

Based on your edit:

EDIT: It seems that the size of the encrypted data is 48 bytes (12 bytes larger than the original). Why is this so? I thought that it only adds bytes if they are not a multiple of the block size (16 bytes, my data is 32 bytes). Is there always always more data and with a constant increase (I need to know that for proper reading and decryption).

If the encrypted data is 48 bytes, it is 16 bytes larger than your original array. This makes sense because the algorithm is with a data pad, because the default is PKCS7 (even if the size matches the block size, since it fits the next multiple of the block size). If you want to keep it exactly 32 bytes, just change Padding to None

 aes.Padding = PaddingMode.None; 
+6
source share

It seems you are treating the length of the plaintext as the length of the ciphertext. This is not a safe guess.

Why do you copy between FileStream and MemoryStream , you can transfer FileStream directly to the encryptor / decoder.

In PKCS7, there is at least one fill byte (to store the number of fill bytes). Thus, the output size will be Ceil16(input.Length + 1) or (input.Length & ~15) + 1 .

+3
source share

In short, AES encrypts messages in blocks of 16 bytes. If your message is not equal to a multiple of 16 bytes, for the last block the algorithm should be slightly different; in particular, the last block must be โ€œpaddedโ€ with a value known to the algorithm as the padding value (usually zero, sometimes something like a character space value).

You do this yourself by putting data into a fixed-length byte array. You added the data yourself, but decrypter now tries to undo the last block and get byte values โ€‹โ€‹that it does not recognize as an addition added by its encrypter equivalent.

The key should not fill out the message. You can use the BitConverter class to pass byte arrays to IConvertible types and types (value types and string types), and then use this instead of rewinding your own byte array. Then, when you decrypt, you can read from the decryption stream to the length of the ciphertext, but do not expect that the decrypted result will have many actual bytes.

+1
source share

All Articles