Python实现AES加解密时出现Incorrect Padding错误求助
问题分析与解决:AES-CBC解密时Padding错误
核心问题
你遇到的ValueError: Padding is incorrect.根本原因是AES-CBC模式必须使用相同的初始化向量(IV)进行加密和解密,而你的代码里加密时自动生成了随机IV,但没有将其与密文一起保存,解密时又生成了新的随机IV,导致解密出的内容完全乱码,最终触发padding校验失败。
另外你疑惑的SHA1哈希每次不同是错误的——SHA1是确定性哈希算法,相同输入会得到完全相同的输出,哈希部分没有问题。
错误细节
当你调用AES.new(key, AES.MODE_CBC)时,如果不指定iv参数,库会自动生成一个随机的16字节IV(AES块大小)。这个IV是加密过程的必要部分,但你的原加密函数没有把IV返回给解密函数,导致解密时又生成了一个新的随机IV,用错误的IV解密必然得到乱码,乱码无法通过padding校验,因此抛出错误。
修正后的代码
加密函数
def encrypt(password, message): # 用SHA1哈希密码,取前16字符作为AES-128密钥 hashed_password = hashlib.sha1(password.encode()).hexdigest() key = hashed_password[:16].encode() # 创建CBC模式加密器,自动生成随机IV cipher = AES.new(key, AES.MODE_CBC) # 填充消息到块大小的整数倍 padded_message = pad(message.encode(), AES.block_size) # 加密消息 ciphertext = cipher.encrypt(padded_message) # 将IV和密文分别转Base64后拼接(用冒号分隔) iv_base64 = base64.b64encode(cipher.iv).decode('utf-8') ciphertext_base64 = base64.b64encode(ciphertext).decode('utf-8') return f"{iv_base64}:{ciphertext_base64}"
解密函数
def decrypt(password, encrypted_text): # 拆分IV和密文部分 iv_base64, ciphertext_base64 = encrypted_text.split(':') iv = base64.b64decode(iv_base64) ciphertext = base64.b64decode(ciphertext_base64) # 生成和加密时一致的密钥 hashed_password = hashlib.sha1(password.encode()).hexdigest() key = hashed_password[:16].encode() # 使用加密时的IV创建解密器 cipher = AES.new(key, AES.MODE_CBC, iv=iv) # 解密消息 padded_message = cipher.decrypt(ciphertext) # 去除填充并解码为字符串 message = unpad(padded_message, AES.block_size).decode() return message
关键说明
- CBC模式下,IV不需要保密,但必须保证每次加密使用随机IV,且加密和解密使用同一个IV。随机IV的作用是避免相同明文和密钥生成相同密文,提高安全性。
- 你之前未哈希密码时能运行,大概率是当时无意间保证了加密和解密的IV一致(比如用了ECB模式,或者硬编码了IV),但ECB模式是不安全的,不建议使用。
现在运行你的测试代码就能正常加密解密了。
内容的提问来源于stack exchange,提问作者Gautam Dhiman
相关产品推荐
相关产品推荐

