I have a server/client system, which encrypts images on the server (python) and decrypts them on the client (c#). The cryptography part is working perfectly, except for trying to decrypt info which is several-blocks long (for example, an image, and not a "Hello World" string).
So, when I try to decrypt encrypted images via a CryptoStream - sometimes it works, and for some reason - sometimes it doesn't.
This is the decryption process of the image:
public static byte[] DecryptBytesFromBytes(byte[] encryptedImage, byte[] key)
{
byte[] decryptedImage;
// Create an Aes object with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = key;
aesAlg.Padding = PaddingMode.Zeros;
aesAlg.Mode = CipherMode.CBC;
byte[] IV = new byte[16];
byte[] cipherBytes = new byte[encryptedImage.Length - IV.Length];
Array.Copy(encryptedImage, IV, IV.Length);
Array.Copy(encryptedImage, IV.Length, cipherBytes , 0, cipherBytes.Length);
aesAlg.IV = IV;
// Create a decryptor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
using (var input = new MemoryStream(cipherBytes))
using (var output = new MemoryStream())
{
using (var cryptStream = new CryptoStream(input, decryptor, CryptoStreamMode.Read))
{
var buffer = new byte[1024];
var read = cryptStream.Read(buffer, 0, buffer.Length);
while (read > 0)
{
output.Write(buffer, 0, read);
read = cryptStream.Read(buffer, 0, buffer.Length); // Error here
}
decryptedImage= output.ToArray();
}
}
return decryptedImage;
}
If it helps, I get the same error even when doing:
cryptStream.CopyTo(output);
This is the python code for encryption:
@staticmethod
def pad(s):
return s + b"\0" * (AES.block_size - len(s) % AES.block_size)
def encrypt(self, message):
message = self.pad(message)
iv = Random.new().read(AES.block_size)
cipher = AES.new(str.encode(self.key), AES.MODE_CBC, iv)
return iv + cipher.encrypt(message)
The Exception
Sometimes I get this error: System.ArgumentException: Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.
The full stacktrace:
at System.Buffer.BlockCopy (System.Array src, System.Int32 srcOffset, System.Array dst, System.Int32 dstOffset, System.Int32 count) [0x00097] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at Mono.Security.Cryptography.SymmetricTransform.InternalTransformBlock (System.Byte[] inputBuffer, System.Int32 inputOffset, System.Int32 inputCount, System.Byte[] outputBuffer, System.Int32 outputOffset) [0x000b0] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at Mono.Security.Cryptography.SymmetricTransform.FinalDecrypt (System.Byte[] inputBuffer, System.Int32 inputOffset, System.Int32 inputCount) [0x00020] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at Mono.Security.Cryptography.SymmetricTransform.TransformFinalBlock (System.Byte[] inputBuffer, System.Int32 inputOffset, System.Int32 inputCount) [0x0002e] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at System.Security.Cryptography.CryptoStream.Read (System.Byte[] buffer, System.Int32 offset, System.Int32 count) [0x002e3] in <d4a23bbd2f544c30a48c44dd622ce09f>:0
at Project.Crypto.DecryptBytesFromBytes (System.Byte[] encryptedImage, System.Byte[] key) [0x000b9] in C:\Users\user\Desktop\Project\Crypto.cs:129
Note that Project.Crypto.DecryptBytesFromBytes
is the decryption function.
Does anybody have any idea why it happens, and how can I fix it? Let me know if more information is needed.
This is what I found in the documentation of the function Read()
:
// Exceptions:
// T:System.ArgumentException:
// Thesum of the count and offset parameters is longer than the length of the buffer.
By the way, I use CBC mode and padding of zeros.
I would like to clarify one last thing - I do this whole process just so I could take encrypted bytes, and turn them into decrypted bytes. If there is another way to decrypt bytes into bytes in c#, please let me know.