pycryptodome & AES CBC:无法解密字符串

pycryptodome & AES CBC : failing to decrypt a string

我正在尝试使用 pycryptodome 和 AES-CBC 实现一个简单的加密解密脚本,即:

from Crypto.Cipher import AES
from Crypto import Random
#import itertools

plain_text = "This is the text to encrypt"
key = "0361231230000000"

def encrypt(plain_text, key):
    key = bytes(key, "UTF-8")
    cipher = AES.new(key, AES.MODE_CBC)
    print("Encryption Cipher: ", cipher)
    # When there is no padding, the block size must equal the cipher length
    # Padding is necessary for texts with length different from 16 bytes
    cbytes = cipher.encrypt(bytes(plain_text[:16], "UTF-8"))
    return cbytes


def decrypt(enc_text):
    k = bytes(key, "UTF-8")
    cipher = AES.new(k, AES.MODE_CBC)
    print("Decryption Cipher: ")
    return cipher.decrypt(enc_text).decode("UTF-8")


if __name__ == "__main__":
    enc_text = encrypt(plain_text, key)
    print(enc_text)

    dec_text = decrypt(enc_text)
    print(dec_text)

错误信息如下: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte

如果在解密过程中我用“Latin-1”替换“UTF-8”,输出不匹配:

Decryption Cipher: 
Ï(¨e¨^î

我错过了什么?

不像ECB, CBC does require an initialization vector. As the documentation说的那样:

If [iv argument] not provided, a random byte string is generated (you must then read its value with the iv attribute).

将其应用于您的代码:

from Crypto.Cipher import AES
from Crypto import Random

plain_text = "This is the text to encrypt"
key = b"0361231230000000"

def encrypt(plain_text, key):
    cipher = AES.new(key, AES.MODE_CBC)
    b = plain_text.encode("UTF-8")
    return cipher.iv, cipher.encrypt(b)

def decrypt(iv, enc_text):
    cipher = AES.new(key, AES.MODE_CBC, iv=iv)
    return cipher.decrypt(enc_text).decode("UTF-8")
    
if __name__ == "__main__":
    iv, enc_text = encrypt(plain_text[:16], key)
    dec_text = decrypt(iv, enc_text)
    print(dec_text)