How to properly encrypt jpeg file using xor operation
I have a problem encrypting a JPEG file using the xor operation. This is how I decode the file:
Stream imageStreamSource = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
JpegBitmapDecoder decoder = new JpegBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource bitmapSource = decoder.Frames[0];
return bitmapSource;
This is how I encode and encrypt it (bs decoded by BitmapSource):
int stride = bs.PixelWidth * 3;
int size = bs.PixelHeight * stride;
byte[] pixels = new byte[size];
bs.CopyPixels(pixels, stride, 0);
pixels = xoring(pixels, size);
int width = bs.PixelWidth;
int height = bs.PixelHeight;
BitmapSource image = BitmapSource.Create(
width,
height,
bs.DpiX,
bs.DpiY,
bs.Format,
bs.Palette,
pixels,
stride);
FileStream stream = new FileStream(outName, FileMode.Create);
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
TextBlock myTextBlock = new TextBlock();
myTextBlock.Text = "Codec Author is: " + encoder.CodecInfo.Author.ToString();
encoder.FlipHorizontal = false;
encoder.FlipVertical = false;
encoder.QualityLevel = 100;
encoder.Rotation = Rotation.Rotate0;
encoder.Frames.Add(BitmapFrame.Create(image));
encoder.Save(stream);
This is the xoring function:
public byte[] xoring(byte[] data, int size)
{
const string key = "abc";
for (int i = 0; i < size; i++)
data[i] = (byte)(data[i] ^ (byte)key[i % key.Length]);
return data;
}
I expect the image to be completely noisy, but I get something like this: http://i.imgur.com/yNQqw8D.png
This source file: http://i.imgur.com/PILmdGL.png
Any help would be appreciated! It seems that only one color channel was encrypted ...
source to share
If you are using a permanent key, there is no chance of a decent level of security. In fact, as your images show, some of the data is still jumping out of the resulting image.
The missing component is a way to change your encryption key during encryption. The most common way is to use the Random generator to create a new encoding byte for each XOR operation.
So the real key would be the seed you use to set up Random at the class level (!):
Random R = new Randowm(2014);
Or perhaps something like:
Random R = new Randowm(imageStreamSource.Length);
This will set it up so that you can decode later.
Then you create an Xor by creating a new key as
byte key = (byte) R.Next(256);
source to share
This problem is similar to the problem with ECB block ciphers .
What happens here is that any repetition of data in your original file also results in repetition in the ciphertext.
For example, if your bits are "00000 ..." in a long section, then the encrypted version will simply be repeated by your key in the same section. The repetition pattern is preserved. (Obviously, this is not a good property of an encryption algorithm for revealing your key like this, but that's a separate issue.)
source to share