python 3 шифрование и дешифрование изображения с использованием AES - PullRequest
1 голос
/ 25 апреля 2020

Я использую AES для шифрования и дешифрования изображения. Я унаследовал код, поэтому, пожалуйста, помогите мне, если вы, ребята, видите что-то не так Я пытаюсь понять и исправить код.

    chunk_size = 64*1024
    output_file = filename+".enc"
    file_size = bytes(os.path.getsize(filename))
    IV = get_random_bytes(16)

    encryptor = AES.new(key, AES.MODE_CBC, IV)
    with open(filename, 'rb') as inputfile:
        with open(output_file, 'wb') as outf:
            outf.write(file_size)
            outf.write(IV)
            while True:
                chunk = bytes(inputfile.read(chunk_size))
                if len(chunk) == 0:
                    break
                elif len(chunk) % 16 != 0:
                   chunk = chunk + bytes(16 - len(chunk)%16)
                outf.write(encryptor.encrypt(chunk))

Мое изображение имеет размер 66 КБ, что составляет 67584 байта. Учитывая, что AES работает с 16 байтами, этот код должен выдавать ошибку, но он генерирует зашифрованный файл. Когда я пытаюсь расшифровать, используя

def decrypt(key, filename):
        chunk_size = 64*1024
        output_file = filename[:-4]
        with open(filename, 'rb') as inf:
            filesize = bytes(inf.read(16))
            IV = inf.read(16)
            decryptor = AES.new(key, AES.MODE_CBC, IV)
            with open(output_file, 'wb') as outf:
                while True:
                    chunk = inf.read(chunk_size)
                    print(len(chunk))
                    if len(chunk)==0:
                        break
                    outf.write(decryptor.decrypt(chunk))
                outf.truncate(filesize)```

, я получаю сообщение об ошибке, как показано ниже

TypeError: требуется целое число (получено байтов типа)

и когда я набираю чанк в байтах, я получаю следующую ошибку

Входные строки должны быть кратны 16 в длину

Я запутался, как я могу исправить ошибку "несколько 16 в длину ", когда мой размер файла на консоли для источника отображается как 65536.

1 Ответ

2 голосов
/ 25 апреля 2020

Размер файла хранится неправильно. Чтобы сохранить размер файла в первых 16 байтах (поскольку он предположительно предназначен для метода decrypt, хотя 16 байтов на самом деле слишком велики) в порядке с прямым порядком байтов, замените в шифровании:

file_size = bytes(os.path.getsize(filename))

с

file_size = os.path.getsize(filename).to_bytes(16, byteorder='big')

и в расшифровке:

filesize = bytes(inf.read(16))

с

filesize = int.from_bytes(inf.read(16), byteorder='big')

С этими изменениями шифрование и дешифрование работают как задумано.

Примечание: Вы используете вариант заполнения нулями для заполнения и сохраняете размер файла (возможно, только) для удаления заполнения после расшифровки. Есть более эффективный метод, заполнение PKCS7. Здесь информация о том, сколько байтов нужно удалить, уже включена в само заполнение. Таким образом, размер файла не должен быть сохранен (по крайней мере, чтобы не удалить отступы). Кроме того, заполнение также поддерживается в PyCryptodome методами pad и unpad.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...