如何使用python

时间:2017-10-27 03:10:06

标签: python image encryption

前言:这是课程所必需的,我知道不应该使用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"),并且我也卡在要填充字节的部分

1 个答案:

答案 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"))