【问题标题】:how to display encrypted image as an image without decrypting it如何在不解密的情况下将加密图像显示为图像
【发布时间】:2017-02-17 14:26:48
【问题描述】:
#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)

我的问题有两个, 1)我将如何将基本上是十六进制字符串的文本文件的加密文件(在hexlify之前是乱码)转换回图像? 我希望输出在任何查看器上都可以作为 jpg 格式查看。

我已经尝试了一些东西,遇到了 Pillow,但我似乎无法掌握它是否可以做我想做的事。

任何帮助将不胜感激。

PS:我也想用其他密码试试这个。所以我认为如果有人能帮助弄清楚这种理解是否正确,将会很有帮助:

jpg -> 转换为二进制/十六进制 -> 加密 -> 乱码输出 -> 转换为 bin/hex -> 转换为 jpg

2) 以上可能吗?应该将它们转换为十六进制还是二进制?

【问题讨论】:

  • 要恢复hexlify + encrypt,应用decrypt + unhexlify?
  • @zvone 有没有办法 hexlify + 加密 -> 转换为 jpg ?为了更清楚,我想知道是否有办法获取乱码密文并将其转换为图像?
  • 当然有办法,但是我还是不明白是什么问题。首先,你为什么将 jpg 转换为十六进制?其次,除了将十六进制转换为原始格式之外,您似乎拥有一切。你在这里:stackoverflow.com/q/9641440/389289
  • @zvone 我试图实现的目标是我有一张我想用 AES 加密的普通照片。我希望得到的密文也能够像照片一样打开。这张密码照片(为了更好的术语)稍后应该能够解密为原始图像。我想我正在转换为十六进制,试图在发帖之前为自己解决这个问题……我被密文难住了。它基本上是不可读的符号。那么如何在不解密的情况下将这样的 txt 文件转换为 jpg(或任何照片格式)(我希望图像只是噪音)
  • 我想如果你只做 ciphertext = obj.encrypt(content)content = obj2.decrypt(ciphertext) 没有任何填充、编码、hexlifying 等,那应该可以工作。

标签: python cryptography pillow pycrypto


【解决方案1】:

这里的问题是如何在不解密的情况下将加密图像显示为图像。

加密内容不是图像,不能明确表示为图像。可以做的最好的就是把它当作一个位图,即每个二进制值代表某种颜色在某个坐标处的强度。

将数据视为每个像素 3 个字节似乎是合乎逻辑的:RGB RGB RGB...

图像是二维的,加密数据只是一个字节列表。同样,有几个选项是有效的。假设它是一个正方形图像(NxN 像素)。

要创建图像,我会使用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

顺便说一句,这可以用任何字节串来完成,而不仅仅是加密的图像。

【讨论】:

  • 这有助于解决问题。我检查了 DES 和 AES 之间的区别。我想检查它是否与说凯撒密码相同。位图是否出卖任何类型的数据。非常感谢 zvone。
猜你喜欢
  • 1970-01-01
  • 2011-12-17
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 2011-10-12
  • 1970-01-01
  • 2018-08-13
  • 2023-03-16
相关资源
最近更新 更多