You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

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()

代码说明

  1. 全程处理字节:从初始密文转字节开始,每次解密的输入和输出都是字节,避免中间解码导致的乱码。
  2. 正确的循环逻辑:每次解密后把结果赋值给current_data,作为下一次解密的输入,确保每一步都是基于上一次的解密结果。
  3. 解填充时机:只有最后一次解密完成后,才对结果进行解填充和解码,因为只有最终明文才是符合编码规则的字符串。
  4. AES实例创建:每次解密都新建AES实例,确保CBC模式的IV正确重置(因为你的多次加密都是用同一个IV独立加密的,不是链式CBC)。

验证结果

n=2时,运行代码应该输出正确的明文:

最终明文: a214868d-f40b-4184-8089-be57330fcd45

如果加密次数是3次,只需要修改n=3即可,代码会自动执行3次解密。

内容的提问来源于stack exchange,提问作者Michael Ajanaku

火山引擎 最新活动