简单 Python AES 解密更长的密文

Simple Python AES decryption for longer ciphertexts

我不是 AES 专家,而且我必须在非常有限的 Python2 环境中提供解密功能。​​

我有一个 32 字节的 key 和一个 16 字节的初始化 vector 以及一个 64 字节的测试密码 message - 所有类型 str。 AES 在密码块链接模式下运行。

使用 pycrypto 一切正常,我得到了 unicode.

类型的 64 符号解密消息
from Crypto.Cipher import AES

cipher = AES.new(key, AES.MODE_CBC, vector)
decryption = cipher.decrypt(message).decode()
print(decryption)

不幸的是,pycrypto 本身在最终环境中不受支持,因为我相信它对 AES 有一些奇特的编译依赖项。 有一个纯粹的 Python 替代方案叫做 pyaes:

import pyaes

cipher = pyaes.AESModeOfOperationCBC(key, vector)
decryption = cipher.decrypt(message[0:16]).decode()
print(decryption)

请注意,我对前 16 个字节进行了切片并正确地得到了解密消息(unicode 类型)的前 16 个符号。

但是,一旦我尝试了完整的消息,我就得到了 ValueError: ciphertext block must be 16 bytes.

即使我切片 message[16:32],我也得到 UnicodeDecodeError: 'ascii' codec can't decode byte 0xb8 in position 0: ordinal not in range(128).

那么在我的案例中如何使用 pyaes 和解密更长的密文?


秘密明文是这样的

{"valueInt":123, "valueFloat":1.23, "valueString":"123"}

尾随(填充)空格。

可能性 1. 消息 [16:32] 的情况是未加密文本的第一部分可能包含多字节字符,因此在占用 16 个字节后,1+ 字节泄漏到 original/unencrypted 字符串。尽管这仅适用于您使用多字节字符的情况。

如果您也在加密它们,如果您的编码是 utf8,您可以先尝试将文本转换为二进制文件:

cipher.encrypt(mystring.encode('utf8'))

反过来

cipher.decrypt(mystring.decode('utf8'))

可能性 2. 如果您使用相同的 AESModeOfOperationCFB 解密,您应该尝试使用新实例进行解密。以下代码无法解密包含无效 ascii 字节的正确文本。

cipher = pyaes.AESModeOfOperationCBC(key, vector)
encrypted = cipher.decrypt('Hello world')
print(encrypted)
# ?Eg?m??K?(|
decrypted = cipher.decrypt(encrypted)
print(decrypted)
# ?XL=?-QE??Y?=k

但是如果你这样做:

encrypter = pyaes.AESModeOfOperationCBC(key, vector)
encrypted = cipher.encrypt('Hello world !!!!')
print(encrypted)
# ?Eg?m??K?(|
decrypter = pyaes.AESModeOfOperationCBC(key, vector)
decrypted = decrypter.decrypt(encrypted)
# Hello world !!!!

如果您使用同一实例加密 2 个块,然后将它们连接起来,则需要一个新实例来解密 2 个新块。或者 encrypt/decrypt 每个块都有一个新实例。