Проблема шифрования AES в режиме CBC с Pycrypto - PullRequest
1 голос
/ 27 мая 2019

У меня следующий код работает как шарм

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad

key = b'Sixteen byte key'
data = 'some text to encrypt'.encode("UTF-8")
data = pad(data, AES.block_size)
encryptor = AES.new(key, AES.MODE_CBC)
iv = encryptor.IV
decryptor = AES.new(key, AES.MODE_CBC, IV=iv)

ciphertext = encryptor.encrypt(data)
print(ciphertext)
plaintext = decryptor.decrypt(ciphertext)
print(unpad(plaintext, 16))

Но когда я пытаюсь преобразовать в функцию, я получаю ошибку заполнения. Мой адаптированный код

def cbc(msg, op):
    key = b'Sixteen byte key'
    encryptor = AES.new(key, AES.MODE_CBC)
    iv = encryptor.IV
    decryptor = AES.new(key, AES.MODE_CBC, IV=iv)
    if op == 1:
        data = msg.encode("UTF-8")
        data = pad(data, AES.block_size)
        ciphertext = encryptor.encrypt(data)
        print(ciphertext)
    else:
        plaintext = decryptor.decrypt(msg)
        print(unpad(plaintext, 16)) 

Мой журнал

Traceback (most recent call last):
  File "D:/Google Drive/max/AES.py", line 48, in <module>
    cbc(b'*\xd3\xc1Y\xc2f;\xf0\xc0@\xd9E\xc5x\x11\xb4', 2)
  File "D:/Google Drive/max/AES.py", line 19, in cbc
    print(unpad(plaintext, 16))
  File "C:\Users\Evilmaax\AppData\Local\Programs\Python\Python36\lib\site-packages\Crypto\Util\Padding.py", line 90, in unpad
    raise ValueError("Padding is incorrect.")
ValueError: Padding is incorrect.

Ошибка возникает в операторе else, когда я пытаюсь расшифровать байтовое сообщение, подобное *\xd3\xc1Y\xc2f;\xf0\xc0@\xd9E\xc5x\x11\xb4. Важное замечание: Это сообщение было сгенерировано оператором if той же функции.

Кто-нибудь знает, почему это происходит? __________________________________________________________

РЕДАКТИРОВАТЬ: Используя совет Роба Нейпира (большое спасибо), я решил проблему. Если у вас возникла та же проблема, это функциональная версия:

def cbc(key, data, op):
if op == 1:
    cipher = AES.new(key, AES.MODE_CBC, iv)
    data = key.encrypt(data)
    print(f"Coded text: {data}")
else:
    decipher = AES.new(key, AES.MODE_CBC, IV=iv)
    print(f'Plaintext: {unpad(decipher.decrypt(data), BLOCK_SIZE).decode("utf-8")}')

1 Ответ

2 голосов
/ 27 мая 2019

Вы генерируете случайный IV, что хорошо, но затем вы выбрасываете его, что означает, что вы не можете расшифровать данные.

Эта строка создает шифратор со случайным IV:

encryptor = AES.new(key, AES.MODE_CBC)

Эта строка создает расшифровщик с тем же IV:

decryptor = AES.new(key, AES.MODE_CBC, IV=iv)

Это нормально в вашем исходном коде, но вы нигде не сохраняете IV, поэтому, когда вы помещаете его в функцию, которую вызываете дважды, вы пытаетесь расшифровать с помощью другого IV, отличного от зашифрованного.

Вам необходимо сохранить IV как часть зашифрованного текста и использовать его во время расшифровки. Если вам нужен пример такого формата, смотрите спецификацию RNCryptor , а если вы хотите увидеть пример в Python, см. RNCryptor-python .

...