前言:这是课程所必需的,我知道不应该使用ECB。
我正在尝试使用AES加密图像,然后显示图像
需要的步骤: 阅读图片, 转换为字节对象, 填充字节, 加密字节, 转换回图像对象, 保存为图像文件
这是我现在的代码:
from PIL import Image
from Crypto.Cipher import AES
from Crypto import Random
img = Image.open("photo.jpg")
img.tobytes()
key = '0123456789abcdef'
mode = AES.MODE_ECB
encryptor = AES.new(key, mode)
img.frombytes("RGB")
此时我被困住了。我得到了一个没有足够的图像数据"线路上的错误" img.frombytes(" RGB"),并且我也卡在要填充字节的部分
答案 0 :(得分:0)
因此,我需要一种以图像形式传输文件的方法(不要问我为什么),如果您只想传输文本,则可以创建一个txt文件。
这可能不是完全解决问题的最佳方法,因为您可能希望在现有图像中隐藏数据,但是无论如何我希望与他人共享代码,以防某人在某处某处出现。
基本上,这将创建大小与文件大小有关的图像,并将3个字节的序列放置在一个像素(RGB)中
所以我写了一个小文件夹2ImageEncoder.py (默认情况下,它将加密名为“ 文件”的文件夹中的所有数据)
from PIL import Image
from pathlib import Path
encryptedImagesFolder = 'encryptedImagesFolder'
Path(f"./{encryptedImagesFolder}").mkdir(parents=True, exist_ok=True)
newLine = b'\new\n\rL'
def encode_data_to_image(data: bytes, imagePath: str):
data += b'FINISH_OF_DATA'
data = str(
{
'path': imagePath,
'data': data
}
)
data = data.encode()
n = int((len(data)/3)**0.5) + 1
print(n, len(data))
img = Image.new('RGB', (n, n))
# data = img.getdata()
encryptedPixelsList = []
pixel = []
if len(data) % 3 != 0:
data += (3 - (len(data) % 3)) * b'\x00'
for i, Byte in enumerate(data):
if i % 3 == 2:
pixel.append(Byte)
encryptedPixelsList.append(tuple(pixel))
pixel = []
else:
pixel.append(Byte)
for _ in range(len(encryptedPixelsList), n**2):
encryptedPixelsList.append((0, 0, 0))
img.putdata(encryptedPixelsList)
imagePath = imagePath.replace('\\', '_')
img.save(f'./{encryptedImagesFolder}/{imagePath}.png')
# img.show()
def encode_folder(folder: Path):
for file in folder.iterdir():
if not file.is_dir():
with open(str(file), 'rb') as rb:
data = rb.readlines()
encode_data_to_image(
data=newLine.join(data),
imagePath=str(file))
else:
encode_folder(folder=file)
if __name__ == '__main__':
# ./files is the name of the folder you want to encrypt
encode_folder(folder=Path(r'./files'))
和一个Image2FilesDecoder.py
这将遍历加密的图像文件夹并检索其以前的形式(在带有加密图像文件夹的另一个文件夹中运行此表单,这样它就不会覆盖原始文件文件夹)
from PIL import Image
from pathlib import Path
newLine = b'\new\n\rL'
def decode_encrypted_images(folder: Path):
for pic in folder.iterdir():
img = Image.open(str(pic))
data = img.getdata()
totalData = []
for pixel in data:
totalData.extend(list(pixel))
decryptedData = bytes(totalData)
try:
decryptedData = eval(
decryptedData[:decryptedData.rfind(b'}')+1].decode())
except:
decryptedData.replace(b'\\', '')
decryptedData = eval(
decryptedData[:decryptedData.rfind(b'}')+1].decode())
decryptedData['data'] = decryptedData['data'][:-14]
filePathObj = Path(decryptedData['path'])
Path(filePathObj.parent).mkdir(
parents=True, exist_ok=True)
writeBytes = decryptedData['data'].split(newLine)
with open(str(filePathObj), 'wb') as wb:
wb.writelines(writeBytes)
if __name__ == '__main__':
decode_encrypted_images(folder=Path(
r".\encryptedImagesFolder"))