Image encrypting with AES c#

172 Views Asked by At

I have to encrypt and decrypt Image by AES each algorithm. I have following code that encrypt Image:

public static byte[] MakeEncryption(Image image, CipherMode mode, byte[] key, byte[] iv)
        {
            using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider { Mode = mode })
            {
                aes.Key = key;
                aes.IV = iv;
                ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);

                byte[] imageBytes;
                using (var mstream = new MemoryStream())
                {
                    image.Save(mstream, image.RawFormat);
                    imageBytes = mstream.ToArray();
                }

                using (MemoryStream input = new MemoryStream(imageBytes))
                using (MemoryStream encrypted = new MemoryStream())
                using (CryptoStream cryptoStream = new CryptoStream(encrypted, encryptor, CryptoStreamMode.Write))
                {
                    input.CopyTo(cryptoStream);
                    return encrypted.ToArray();
                }
            }
        }

And following code to convert byte array to Image:

public static Image GetImage(byte[] bytes)
        {
            Image img;
            using (var ms = new MemoryStream(bytes))
            {
                ms.Position = 0;
                ms.Write(bytes, 0, bytes.Length);
                img = Image.FromStream(ms); // this line cause to ArgumentException
            }

            return img;
            
        }

Every time i run my code i had the same problem: System.ArgumentException in line with comment

Any idea what is wrong?

I tried many ways of loading image into encrypting function, many ways of using different types of Stream, nothing helped

1

There are 1 best solutions below

3
Maarten Bodewes On

The RawFormat property seems to reference the "file format" of the image, e.g. Jpeg. It in itself may not represent a raw image in the sense that it just contains the color information for each pixel.

After encryption of the, for instance JPEG encoded image, you can of a be sure that the meta information that is required to translate the image back to a bitmap is lost during encryption. In other words, the ciphertext won't represent an image anymore. Decoding such an image won't result in a distorted image, it will just abort on first few bytes of the header.

You could try the MemoryBmp to get as close to pixels as possible. But please note that an image still has other data such as the width and height encoded somewhere. The size will also be altered if you are encrypting using CBC. Bmp also has the raw image stored inside, but you'd have to parse the format to find the pixels.

Encrypting the entire image and just displaying a static or newly created, randomized image of the same dimensions would be much easier than trying to find each pixel and encrypting those separately (or something similar).