Reputation: 4486
I'd like to be able to convert/display an AES256 asymmetric encrypted image even if it appears to be garbage, I've read a number of things on SO that suggest removing the headers and then reattaching them afterward so even if looks nutty it still displays it.
The point of this is that I want to see if it's possible to perform image classification on an image dataset encrypted with a known public key. If I have a picture of a cat and I encrypt it with exactly the same key, then the result will generally be reproducible and result in an image that in some way equates to the original.
Excuse the lack of code, I didn't want to pollute the discussion with ideas that I was considering in order to get a proper critique from you lovely people- I would say I'm not an encryption expert hence my asking for advice here.
Upvotes: 3
Views: 3133
Reputation: 6414
I'm using an answer, although it's not an answer because I'd like to show two pictures to demonstrate.
Both pictures were taken from my blog entry http://javacrypto.bplaced.net/g01-ecb-pinguin/ (German language).
The first picture shows the Tuc penguin after encryption with AES in ECB mode:
The form still persists, and you can "imagine" what animal is shown.
The second picture was encrypted with AES in CBC mode and the output is looking like garbage:
The conclusion: if the picture was encrypted with a mode like CBC, CTR or GCM you will always get something like the second picture, even if you know the mode, key and initialization vector that was in use.
A visual comparison will not work, sorry.
To answer your question in comment "how would you display encrypted images in their encrypted form": you can't show them because usually a picture has a header that gets encrypted as well, so this information will be lost. The two "encrypted" pictures were created by stripping off the header before encryption, then the picture data gets encrypted, and the header is prepended.
Upvotes: 3
Reputation: 32104
There are many options, but I suggest to follow the following guidelines:
img.jpg
file for example).I hope you know Python...
Here is a Python code sample that demonstrates the encoding and decoding procedures:
import cv2
import numpy as np
from Crypto.Cipher import AES
# https://stackoverflow.com/questions/61240967/image-encryption-using-aes-in-python
key = b'Sixteen byte key'
iv = b'0000000000000000'
# Read image to NumPy array - array shape is (300, 451, 3)
img = cv2.imread('chelsea.png')
# Pad zero rows in case number of bytes is not a multiple of 16 (just an example - there are many options for padding)
if img.size % 16 > 0:
row = img.shape[0]
pad = 16 - (row % 16) # Number of rows to pad (4 rows)
img = np.pad(img, ((0, pad), (0, 0), (0, 0))) # Pad rows at the bottom - new shape is (304, 451, 3) - 411312 bytes.
img[-1, -1, 0] = pad # Store the pad value in the last element
img_bytes = img.tobytes() # Convert NumPy array to sequence of bytes (411312 bytes)
enc_img_bytes = AES.new(key, AES.MODE_CBC, iv).encrypt(img_bytes) # Encrypt the array of bytes.
# Convert the encrypted buffer to NumPy array and reshape to the shape of the padded image (304, 451, 3)
enc_img = np.frombuffer(enc_img_bytes, np.uint8).reshape(img.shape)
# Save the image - Save in PNG format because PNG is lossless (JPEG format is not going to work).
cv2.imwrite('enctypted_chelsea.png', enc_img)
# Decrypt:
################################################################################
key = b'Sixteen byte key'
iv = b'0000000000000000'
enc_img = cv2.imread('enctypted_chelsea.png')
dec_img_bytes = AES.new(key, AES.MODE_CBC, iv).decrypt(enc_img.tobytes())
dec_img = np.frombuffer(dec_img_bytes, np.uint8).reshape(enc_img.shape) # The shape of the encrypted and decrypted image is the same (304, 451, 3)
pad = int(dec_img[-1, -1, 0]) # Get the stored padding value
dec_img = dec_img[0:-pad, :, :].copy() # Remove the padding rows, new shape is (300, 451, 3)
# Show the decoded image
cv2.imshow('dec_img', dec_img)
cv2.waitKey()
cv2.destroyAllWindows()
Idea for identifying the encrypted image:
key
and the iv
.Upvotes: 5