Python AES解密报Padding is incorrect填充错误排查
问题根因
ValueError: Padding is incorrect 报错的直接原因是AES解密密钥错误,解密后得到的内容是乱码,不符合PKCS7填充规则,导致unpad函数校验失败。密钥错误通常由两类问题导致:
- 计算共享密钥
sk时依赖了可能存在粘贴错误的给定key参数 - 共享密钥
sk转MD5值的处理逻辑和加密端实际运行逻辑不一致
修复方案
1. 绕开可能错误的给定key值,直接通过私钥计算sk
加密逻辑中sk仅和素数prime、私钥privkey有关,不需要依赖外部传入的key参数,直接通过私钥推导即可,完全避免key值多抄、漏抄带来的计算偏差:
# 替换原有 sk = pow(key, privkey, prime) 逻辑 sk = pow(pow(2, privkey, prime), privkey, prime)
可以先校验下你手里的key是否正确:对比pow(2, privkey, prime)的输出和题目给的十进制key值,如果不相等,说明三个参数(prime/privkey/key)中至少有一个粘贴错误。
2. 逐一验证sk转MD5密钥的常见写法
很多代码贴文会省略哈希输入的细节,不要默认只用str(sk).encode()处理sk,以下三种是CTF题目中最常见的sk转AES密钥逻辑,逐一测试即可找到正确密钥:
from Crypto.Util.number import long_to_bytes import hashlib from Crypto.Cipher import AES # 方式1:十进制字符串转字节后哈希(和你原有逻辑一致) k1 = hashlib.md5(str(sk).encode()).digest() # 方式2:十六进制字符串(去掉0x前缀)转字节后哈希 k2 = hashlib.md5(hex(sk)[2:].encode()).digest() # 方式3:sk直接转大端字节串后哈希(出题人最常写错文档的实现方式) k3 = hashlib.md5(long_to_bytes(sk)).digest()
测试时先不要调用unpad,直接解密打印原始字节,结果中出现flag{前缀的就是正确密钥:
# 以测试k3为例 cipher = AES.new(k3, AES.MODE_ECB) raw_res = cipher.decrypt(bytes.fromhex(flag)) print(raw_res)
3. 特殊情况处理
如果用正确密钥解密后仍然报填充错误,直接手动去掉末尾的填充字节即可:PKCS7填充的最后一个字节的值就是填充字节的总长度,比如最后一个字节是\x03,就去掉最后3个字节,不需要依赖unpad函数。
内容的提问来源于stack exchange,提问作者Magnus Tan
相关产品推荐
相关产品推荐

