Search code examples
pythonimageencryption-symmetric

Why is hexcode output failing?


from os import urandom
from PIL import Image
import io



for y in range((len(array2) -1), -1, -1):  
  decrypted_initial = decrypt(array2[y], key)
  if y > 0:
    decrypted_cipher = decrypt(decrypted_initial, array2[(y -1)])
  if y == 0:
    decrypted_cipher = decrypt(decrypted_initial, fixed_initialization_vector)
  immage_array.append(decrypted_cipher)
immage_array = [x for sets in immage_array for x in sets] #The list is all zeros since the image is all black.


for i in range(1000):
  print (immage_array[i]) #1000 zeroes printed.
if immage_array == myMessage: #Comparing the input hexocde for the encryption and output hexcode from the decryption.
    print("Yay.") #Print successful. 
image = Image.open(io.BytesIO(bytes(immage_array))) #Not sure what this does exactly. I am just trying to get the hexcode to output as an image file.
image.save(output.png)

I am trying to do chain block cipher on an image and this is part of the code. I have been able to get the hex code of an image, encrypt it using chain block cipher, and decrypt it. I then compared the decrypted hex code with the original input hex code and I get a successful match. The hex code is returned as a list instead of a byte array though but the if statement still recognizes them as equal. I am having trouble converting the hexcode back into an image though.

I get this error. OSError: cannot identify image file <_io.BytesIO object at 0x039F1090>

The image is all black pixels for test purposes to make it easy to confirm the integrity of the hex code which I have confirmed to be identical to the input.

What is preventing me from turning the hexcode back into an image? I have tried looking everywhere for examples that worked but I have never been able to fully understand why it worked. Here is my logic.

immage_array is a list == (0, 0, 0, 0, ..., n)

bytes() #turns the immage_array list of all integers 0 into a byte array all consisting of x00.

io.BytesIO() A function needed for the byte array to be manipulated by the Image.open() function.

I then have the byte array stored as an object in the variable image.

image.save(output.png) The save function takes the filename as an argument. The image object is used.

I have honestly tried my hardest to find out where the logic is failing. I would appreciate an explanation of how to turn a list of (0, 0, 0, ..., n) into an image. Yes, I know, I have seen other examples of it being done on stack overflow. I am wondering why my implementation of it is failing.


Solution

  • I just re-read your question. You cannot do this if your immage_array is [0, 0, 0...]. That is not an image, it is a bitmap (subtle difference). Use the PIL.Image.frombytes constructor.

    If you want to encrypt images, just encrypt the whole contents, rather than extracting the file contents, converting it to a bitmap, then encrypting/decrypting it. When you convert it to a bitmap, for starters, it will be an order of magnitude more data, and secondly you loose the information on what format the image is (RGB, ARGB, monochrome, etc.)

    As you have now disclosed, you are using the PIL.Image.getdata method. This returns a one-dimensional list, so how are you going to know the width/height at the other end? i.e. if your image is 640x480, from the other end you can't tell if it will be 480x640 or even 307200x1