Python中AES解密报错:ord()期望字符但遇空字符串问题
问题分析与修复方案
错误原因
- 密文截断逻辑错误:你在解密时执行
enc[AES.block_size:],将base64解码后的密文直接切掉前16字节(AES块大小),但目标密文RLs4yZ1Ku0Ylf4CfVShU1g==解码后长度正好是16字节,截断后得到空字符串,解密结果依然为空,导致unpad函数执行s[:-ord(s[len(s)-1:])]时,s[len(s)-1:]为空,触发ord()参数错误。 - 字节与字符串类型混淆:
cipher.decrypt()返回bytes类型,但你的unpad函数是为字符串设计的,直接传入bytes会导致索引操作得到bytes片段,无法直接用ord()处理。 - IV长度不符合要求:AES-CBC模式要求IV长度必须等于块大小(16字节),你当前的IV
b'123edfr4@#90&65$'长度为15字节,会导致解密逻辑异常。
修复后的代码
import base64 from Crypto.Cipher import AES BS = 16 # 调整pad/unpad函数以适配bytes类型 pad = lambda s: s + (BS - len(s) % BS) * bytes([BS - len(s) % BS]) unpad = lambda s : s[:-s[-1]] class AESCipher: def __init__(self): # 确保key长度符合AES标准:16(AES-128)/24(AES-192)/32(AES-256)字节 self.key = b'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' # 32字节对应AES-256 # 修正IV为16字节长度 self.iv = b'123edfr4@#90&65$1' def encrypt(self, data): cipher = AES.new(self.key, AES.MODE_CBC, self.iv) _pad = pad(data.encode('utf-8')) response = base64.b64encode(cipher.encrypt(_pad)).decode('utf-8') print(response) def decrypt(self, data): enc = base64.b64decode(data) cipher = AES.new(self.key, AES.MODE_CBC, self.iv) # 移除错误的密文截断操作 decrypted_bytes = cipher.decrypt(enc) response = unpad(decrypted_bytes).decode('utf-8') print(response) return response def test(): response = AESCipher().decrypt('RLs4yZ1Ku0Ylf4CfVShU1g==') return response output = test()
关键修复点说明
- 移除无效截断:删除
enc[AES.block_size:],直接使用完整解码后的密文解密,因为目标密文并未附加IV前缀。 - 适配bytes类型处理:重新定义pad/unpad函数,直接操作bytes类型,利用bytes最后一位的数值作为填充长度,避免
ord()的类型冲突。 - 修正IV长度:将IV补全为16字节,满足AES-CBC模式的强制要求。
内容的提问来源于stack exchange,提问作者Sarath Chandran
相关产品推荐
相关产品推荐

