使用PyCryptodome进行AES-CBC 256模式解密时遇填充错误求助
AES-CBC解密填充边界错误的解决方案
问题描述
参考PyCryptodome的CBC模式示例编写解密代码,目标密文可在在线加解密服务中正常解密,但本地代码运行报错:ValueError: Data must be padded to 16 byte boundary in CBC mode。原代码如下:
import hashlib from base64 import b64encode, b64decode from Crypto.Cipher import AES from Crypto.Util.Padding import unpad def decipher(): secret_key = 'secret key' secret_iv = 'secret iv' key = hashlib.sha256(secret_key.encode('utf-8')).hexdigest()[:32].encode("utf-8") iv = hashlib.sha256(secret_iv.encode('utf-8')).hexdigest()[:16].encode("utf-8") s = 'HNAQf+1/fZXxzGTdVUs1qg==' s = str.encode(s) cipher = AES.new(key, AES.MODE_CBC, iv=iv) plain_text = unpad(cipher.decrypt(s), AES.block_size) #<-- this line return plain_text
问题根源
核心错误是未对Base64编码的密文做解码处理。给定的密文是Base64格式字符串,直接编码成字节传给cipher.decrypt()后,数据长度不符合AES固定16字节的块大小要求,因此触发填充边界错误。
密钥和IV的生成逻辑是正确的:通过SHA256哈希的十六进制字符串截取对应长度,编码后分别得到符合AES-256要求的32字节密钥,以及CBC模式要求的16字节IV。
修复后的代码
import hashlib from base64 import b64encode, b64decode from Crypto.Cipher import AES from Crypto.Util.Padding import unpad def decipher(): secret_key = 'secret key' secret_iv = 'secret iv' # 生成256位AES密钥(32字节) key = hashlib.sha256(secret_key.encode('utf-8')).hexdigest()[:32].encode("utf-8") # 生成CBC模式所需的16字节IV iv = hashlib.sha256(secret_iv.encode('utf-8')).hexdigest()[:16].encode("utf-8") # 对Base64密文解码,得到原始二进制密文 ciphertext = b64decode('HNAQf+1/fZXxzGTdVUs1qg==') cipher = AES.new(key, AES.MODE_CBC, iv=iv) # 解密后去除填充 plain_text = unpad(cipher.decrypt(ciphertext), AES.block_size) return plain_text.decode('utf-8') # 可选:将字节转换为UTF-8字符串
关键修复说明
- 替换
str.encode(s)为b64decode(s):必须先将Base64格式的密文解码为原始二进制数据,才能被AES解密函数正确处理。 - 可选添加
.decode('utf-8'):将解密得到的字节数据转换为可读的字符串,便于结果查看。
内容的提问来源于stack exchange,提问作者Robb
相关产品推荐
相关产品推荐

