从加密图像创建 jpg/png

Mrk*_*dig 3 image-processing encryption-asymmetric public-key-encryption

我希望能够转换/显示 AES256 非对称加密图像,即使它看起来是垃圾,我读过一些关于 SO 的内容,建议删除标头,然后重新附加它们,所以即使看起来很疯狂仍然显示它。

重点是我想看看是否可以对使用已知公钥加密的图像数据集执行图像分类。如果我有一张猫的图片,并使用完全相同的密钥对其进行加密,那么结果通常是可重现的,并产生在某种程度上与原始图像相同的图像。

请原谅缺少代码,我不想用我正在考虑的想法来污染讨论,以便从你们可爱的人们那里得到适当的批评——我想说我不是加密专家,因此我在这里寻求建议。

Rot*_*tem 5

There are many options, but I suggest to follow the following guidelines:

  • Encrypt the image data, and not the image file.
    In case the image is 100x100x3 bytes, encrypt the 30000 bytes (not the img.jpg file for example).
    (The down side is that metadata is not saved as part of the encrypt image).
  • Use lossless image file format to store the encrypted image (PNG file format for example, and not JPEG format).
    Lossy format like JPEG is going to be irreversible.
  • Set the resolution of the encrypted image to the same resolution as the input image.
    That way you don't need to store the image headers - the resolution is saved.
    You may need to add padding, so the size in bytes be a multiple of 32.

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()
Run Code Online (Sandbox Code Playgroud)

Encrypted image:
在此输入图像描述

Decrypted image:
在此输入图像描述


Idea for identifying the encrypted image:

  • Compute a hash of the encrypted image, and store it in your database, along the original image, the key and the iv.
  • When you have the encrypted image, compute the hash, and search for it in your database.