Joe*_*rry 5 python encryption image
前言:这是一门课所必需的,我知道不应该使用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")
Run Code Online (Sandbox Code Playgroud)
在这一点上,我被卡住了。我在“img.frombytes(“RGB”)行上收到“图像数据不足”错误,并且还卡在填充字节的部分
所以我需要一种以图像形式传输文件的方法(不要问我为什么),如果你只想传输文本你可以创建一个txt文件。
这可能不完全是问题的最佳解决方案,因为您可能想要一种将数据隐藏在现有图像中的方法,但无论如何我想分享代码,以防它会在某个地方帮助某人。
基本上,这将创建一个大小取决于文件大小的图像,并将 3 个字节的序列放入一个像素 (RGB)
所以我写了一个小folder2ImageEncoder.py(默认情况下它将加密位于名为“ files ”的文件夹中的所有数据)
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'))
Run Code Online (Sandbox Code Playgroud)
和 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"))
Run Code Online (Sandbox Code Playgroud)