AES-256-CBC字符串多次递归解密技术问题求助
解决AES-CBC多次解密的循环逻辑与编码问题
咱们一步一步来解决你的问题:
核心问题分析
你遇到两个主要问题:
- 循环解密时没有正确更新输入值,导致重复解密同一个内容
- 过早解码解密结果,导致中间步骤出现编码乱码
为什么会乱码?
AES加密/解密操作的对象是字节序列,而不是字符串。中间解密得到的结果只是上一次加密的输入字节,这些字节不一定符合UTF-8或ISO-8859-1的编码规则,强行解码必然会出现乱码。只有最后一次解密得到的最终明文才是可解码的合法字符串。
为什么循环失效?
你之前的代码里,第一次解密后得到字符串x,然后循环中反复用decrypt_again(x),但既没有把y赋值给x更新输入,还错误地把解密后的字符串当作十六进制来处理——这完全不符合多次加密/解密的逻辑(多次加密是:明文→字节→加密→字节→加密→...→十六进制存储;所以解密应该是:十六进制→字节→解密→字节→解密→...→明文字节→解码)。
修正后的代码实现
我们重构代码,全程处理字节,只在最后一步解码成字符串:
from Crypto.Cipher import AES # 密钥和IV(保持你原来的配置) k = '57067125438768260656188878670043' key = bytes(k, 'ascii') i = '5706712543876826' iv = bytes(i, 'ascii') # 加密次数(可修改为3、4等任意次数) n = 2 # 初始密文(十六进制格式) cipher_hex = 'dd3364461dbca39ddb5eb32e9f11b81f000acac9ce8b91369f8bf7e4a88787785a8cc498c85ea20370e68f0e7014e92a2b5aedd4c670ec172d7adb45dfa5a770b582e8ed255bb857d94afdfd6e579525f24890070f984b8862133eda9cbb118ba7880db125c32dea7e7c54bc77abfc02' def unpad(byte_data): """针对字节数据的PKCS7解填充(保持和加密时一致的填充规则)""" # 最后一个字节的值就是填充的长度 padding_length = byte_data[-1] return byte_data[:-padding_length] def main(): # 1. 把十六进制密文转成字节,作为初始解密输入 current_data = bytes.fromhex(cipher_hex) # 2. 执行n次解密操作 for _ in range(n): # 每次解密都创建新的AES实例(确保CBC模式的IV正确初始化) decryptor = AES.new(key, AES.MODE_CBC, iv) current_data = decryptor.decrypt(current_data) # 3. 最后一步解填充并解码成明文字符串 plaintext = unpad(current_data).decode('utf-8') print("最终明文:", plaintext) if __name__ == "__main__": main()
代码说明
- 全程处理字节:从初始密文转字节开始,每次解密的输入和输出都是字节,避免中间解码导致的乱码。
- 正确的循环逻辑:每次解密后把结果赋值给
current_data,作为下一次解密的输入,确保每一步都是基于上一次的解密结果。 - 解填充时机:只有最后一次解密完成后,才对结果进行解填充和解码,因为只有最终明文才是符合编码规则的字符串。
- AES实例创建:每次解密都新建AES实例,确保CBC模式的IV正确重置(因为你的多次加密都是用同一个IV独立加密的,不是链式CBC)。
验证结果
当n=2时,运行代码应该输出正确的明文:
最终明文: a214868d-f40b-4184-8089-be57330fcd45
如果加密次数是3次,只需要修改n=3即可,代码会自动执行3次解密。
内容的提问来源于stack exchange,提问作者Michael Ajanaku




