代码的主要问题是没有为AES.new()提供nonce。OCB需要nonce;如果不提供nonce,则每次创建新的AES对象时都会创建一个随机nonce,因此解密将失败。nonce (byte string): a non-repeatable value, of length between 1 and 15 bytes.. If not present, a random nonce of the recommended length (15 bytes) will be created.
有两个选项,要么创建一个nonce并将其传递给AES.new()(在加密和解密中),要么在加密期间使用AES创建的随机nonce。
接下来,OCB是一个经过身份验证的加密算法,但似乎您没有检查MAC。这很重要,因为MAC验证密文的完整性。
AES的加密和解密方法接受和返回字节。您可以使用.decode()将纯文本(如果是文本)转换为字符串。如果你想将密文转换成字符串,你必须先对它进行base64编码,以便将原始字节编码成ASCII字符(只需记住在解密之前解码)。b64encode()也返回字节,但可以很容易地转换为字符串。
举个例子from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from base64 import b64encode
key = get_random_bytes(16) # A 16 byte key for AES-128
nonce = get_random_bytes(15)
message = "A really secret message. Not for prying eyes.".encode()
cipher = AES.new(key, AES.MODE_OCB, nonce=nonce)
ciphertext, mac = cipher.encrypt_and_digest(message)
cipher = AES.new(key, AES.MODE_OCB, nonce=nonce)
plaintext = cipher.decrypt_and_verify(ciphertext, mac)
print(b64encode(ciphertext).decode())
#CSwHy3ir3MZ7yvZ4CzHbgYOsKgzhMqjq6wEuutU7vJJTJ0c38ExWkAY1QkLO
print(plaintext.decode())
#A really secret message. Not for prying eyes.
请注意,如果.decrypt_and_verify()无法验证MAC,则将引发异常,因此您可能需要使用try-except块。值nonce和mac不是秘密值,可以安全地存储在密文旁边。
最后,如果计划从密码短语派生密钥,则应使用基于密码的KDF。kdf创建强键,使用salt和迭代,并且它们非常抵抗fruteforce攻击。您将在^{}中找到KDF函数。