我想对字符串进行 AES 加密和解密。但是密钥和消息必须以字节为单位,所以我通过这样做将消息转换为字节:
b"string"
这是我的 AES 代码:
# Encryption
encryption_suite = AES.new(b'1234567812345678', AES.MODE_OCB)
cipher_text = encryption_suite.encrypt(b"A really secret message. Not for prying eyes.")
# Decryption
decryption_suite = AES.new(b'1234567812345678', AES.MODE_OCB)
plaintext = decryption_suite.decrypt(cipher_text)
但是我需要将解密的纯文本转回字符串以便阅读。目前明文看起来像这样:
b’x\x85\x92\x9d\xe6\x0bJ\xfe\x9b(\x10G\x8e\x05\xc5\xf4\xcdA9\xc18\xb8_\xf9vbmK\x16\xf8\xa3\xb6’
我尝试使用
plaintext.decode(encoding='windows-1252')
和
plaintext.decode("utf-8").strip('\x00')
但我得到的只是:
UnicodeDecodeError: ‘charmap’ 编解码器无法解码位置 3 中的字节 0x9d:字符映射到
或这个:
UnicodeDecodeError: ‘utf-8’ 编解码器无法解码位置 1 中的字节 0xb1:无效的起始字节
我需要将这些字节转换回可读字符串。如果您能提供帮助,我们将不胜感激。
原文由 MNS 发布,翻译遵循 CC BY-SA 4.0 许可协议
您的代码的主要问题是您没有向
AES.new()
提供随机数。 OCB 需要随机数;如果您不提供一个随机数,则每次您创建一个新的 AES 对象时都会创建一个随机数,因此解密将失败。从 文档:
您有两个选择,要么创建一个随机数并将其传递给
AES.new()
(在加密和解密中),要么在加密期间使用AES
创建的随机数。接下来,OCB 是一种经过身份验证的加密算法,但您似乎没有检查 MAC。这很重要,因为 MAC 会验证密文的完整性。
AES
的加密和解密方法接受和返回字节。您可以使用.decode()
将明文(如果是文本)转换为字符串。如果您想将密文转换为字符串,您必须先对其进行 base64 编码,以便将原始字节编码为 ASCII 字符(请记住在解密前解码)。b64encode()
也返回字节,但可以轻松转换为字符串。一个例子,
请注意,如果
.decrypt_and_verify()
无法验证 MAC aValueError
将引发异常,因此您可能需要使用 try-except 块。nonce
和mac
值不是秘密的,将它们存储在密文旁边是安全的。最后,如果您计划从密码短语派生密钥,您应该使用基于密码的 KDF。 KDF 创建强键,使用 salt 和迭代,并且它们非常能抵抗 fruteforce 攻击。您将在
Crypto.Protocol.KDF
中找到 KDF 函数。