rohanKumar rohanKumar - 1 month ago 12
Python Question

how to view encrypted image as is without decryption

#encrypting an image using AES
import binascii
from Crypto.Cipher import AES


def pad(s):
return s + b"\0" * (AES.block_size - len(s) % AES.block_size)

filename = 'path to input_image.jpg'
with open(filename, 'rb') as f:
content = f.read()

#converting the jpg to hex, trimming whitespaces and padding.
content = binascii.hexlify(content)
binascii.a2b_hex(content.replace(' ', ''))
content = pad(content)

#16 byte key and IV
#thank you stackoverflow.com
obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
ciphertext = obj.encrypt(content)

#is it right to try and convert the garbled text to hex?
ciphertext = binascii.hexlify(ciphertext)
print ciphertext

#decryption

obj2 = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
plaintext = obj2.decrypt(ciphertext)
#content = content.encode('utf-8')
print plaintext
#the plaintext here matches the original hex input file as it should


with open('path to - AESimageDecrypted.txt', 'wb') as g:
g.write(plaintext)


My question is two fold,
1) how would i go about converting the encrypted file (which is garbled before hexlify) which is basically a text file of hex strings, back into an image?
i'd like the output to be viewable as a jpg on any viewer.

I've tried a few things out , came across Pillow, except i can't seem to grasp if it can do what i want.

Any help would be appreciated thanks.

PS: i want to try this with other ciphers too. so i think it'd be helpful if anyone can help clear out if this understanding is right:

jpg -> convert to binary/hex -> encrypt -> garbled output -> convert to bin/hex -> convert to jpg

2) is the above possible? and should they be converted to hex or bin?

Answer

The question here is how to display encrypted image as an image without decrypting it.

The encrypted contents are not an image and cannot be unambiguously represented as an image. The best that can be done is to treat it as a bitmap, i.e. each binary value represents the intensity of some color at some coordinate.

It seems logical to treat the data as 3 bytes per pixel: RGB RGB RGB...

Images are 2D and encrypted data is just a list of bytes. Again, several options are valid. Let's say it is a square image (NxN pixels).

To create the image, I would use PIL / Pillow:

from PIL import Image

# calculate sizes
num_bytes = len(cyphertext)
num_pixels = int((num_bytes+2)/3)                     # 3 bytes per pixel
W = H = int(math.ceil(num_pixels ** 0.5))             # W=H, such that everything fits in

# fill the image with zeros, because probably len(imagedata) < needed W*H*3
imagedata = cyphertext + '\0' * (W*H*3 - len(cyphertext))

image = Image.fromstring('RGB', (W, H), imagedata)         # create image
image.save('C:\\Temp\\image.bmp')                          # save to a file

BTW, this can be done with absolutely any string of bytes, not just encrypted images.

Comments