pycryptodome & AES CBC:无法解密字符串
pycryptodome & AES CBC : failing to decrypt a string
我正在尝试使用 pycryptodome 和 AES-CBC 实现一个简单的加密解密脚本,即:
- 没有 iv,
- 没有填充,因此要加密的字符串被剥离为 16 个字符
- key不是随机的,是一个固定的字符串。
但是我通过解密消息失败了。
这是脚本:
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)
我正在尝试使用 pycryptodome 和 AES-CBC 实现一个简单的加密解密脚本,即:
- 没有 iv,
- 没有填充,因此要加密的字符串被剥离为 16 个字符
- key不是随机的,是一个固定的字符串。 但是我通过解密消息失败了。 这是脚本:
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)