简单 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 每个块都有一个新实例。
我不是 AES 专家,而且我必须在非常有限的 Python2 环境中提供解密功能。
我有一个 32 字节的 key 和一个 16 字节的初始化 vector 以及一个 64 字节的测试密码 message - 所有类型 str
。 AES 在密码块链接模式下运行。
使用 pycrypto
一切正常,我得到了 unicode
.
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 每个块都有一个新实例。