user2775380
user2775380

Reputation: 77

How to encrypt jpeg file correctly using xor operation

I have a problem with encrypting JPEG file using xor operation. Here is how I am decoding 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; 

Here is how I am encoding and encrypting it(bs is decoded 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 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 am expecting the image to be completly noise, but I am getting something like this: https://i.sstatic.net/eHnLu.png

This the original file: https://i.sstatic.net/fLw71.png

I would appreciate any help! It seems like if only one color channel was encrypted...

Upvotes: 3

Views: 1434

Answers (2)

TaW
TaW

Reputation: 54433

If you use a constant key there is no chance for a decent level of security. In fact, as your images show some of the data still 'jump' out of the resulting image..

The missing component is a way to change your encoding key during encrytion. The most obviuos way is to use a Random generator to create a new encoding byte for each XOR operation.

This way the real key will be the seed you use to setup the Random at class level(!):

Random R = new Randowm(2014);

Or possibly something like:

Random R = new Randowm(imageStreamSource.Length);

This will set it up in a way that will allow you to decode later.

You then Xor by creating fresh key as

byte key = (byte) R.Next(256);

Upvotes: 3

Wim Coenen
Wim Coenen

Reputation: 66733

This problem is similar to the issues with the ECB mode of 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..." over a long stretch, then the encrypted version will just be your key repeated over the same stretch. The pattern of repetition is preserved. (Obviously it is not a good property of an encryption algorithm to reveal your key like that, but that's a separate issue.)

Upvotes: 3

Related Questions