Ошибка PyCryptodome: ошибка проверки MAC-адреса

Я работаю над программой шифрования с Pycryptodome в Python 3. Я пытаюсь зашифровать (байтовую) строку, а затем расшифровать ее и проверить тег MAC. При проверке выдает ошибку.

Это код:

from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes

aes_key = get_random_bytes(24)
aes_cipher = AES.new(aes_key, AES.MODE_GCM)
encrypted, MACtag = aes_cipher.encrypt_and_digest(b"A random thirty two byte string.")

# Imagine this is happening somewhere else
new_aes_cipher = AES.new(aes_key, AES.MODE_GCM, nonce=aes_cipher.nonce)
new_aes_cipher.verify(MACtag)
decrypted = new_aes_cipher.decrypt(encrypted)

И это ошибка:

Traceback (most recent call last):
  File "aespractice.py", line 10, in <module>
    new_aes_cipher.verify(tag)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-
packages/Crypto/Cipher/_mode_gcm.py", line 441, in verify
    raise ValueError("MAC check failed")
ValueError: MAC check failed

Я просмотрел документацию, и мне кажется, что все в порядке. Как вы думаете, почему программа ведет себя таким образом? Любая помощь будет оценена по достоинству.


person purple_dot    schedule 05.02.2018    source источник


Ответы (1)


Если вы посмотрите на диаграмму состояний для аутентифицированных режимов:

введите описание изображения здесь

Вы видите, что verify() нужно вызывать в самом конце, после того, как произошло какое-либо decrypt(). Итак, либо вы инвертируете вызовы, либо заменяете их комбинированным decrypt_and_verify().

person SquareRootOfTwentyThree    schedule 05.02.2018
comment
Спасибо, но у меня есть еще один вопрос. В чем разница между дайджестом() и шестнадцатеричным дайджестом()? - person purple_dot; 05.02.2018
comment
hexdigest() возвращает digest(), уже закодированное как шестнадцатеричная строка - person SquareRootOfTwentyThree; 05.02.2018