You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义16字节块DES解密后文本乱码,如何修复?

修复自定义Feistel DES加密解密乱码问题

你的核心问题是解密逻辑错误调用了encrypt方法,Feistel结构的解密需要逆序使用子密钥并反转轮次流程,同时存在CBC模式IV长度不匹配、PKCS5去填充不严谨的问题。以下是完整修复方案:

修复后的完整代码

import pyDes

class CustomDES:
    def __init__(self, key, iv):
        # 192位密钥分3个8字节子密钥
        if len(key) != 24:
            raise ValueError("密钥必须为24字节(192位)")
        self.k1 = key[:8]
        self.k2 = key[8:16]
        self.k3 = key[16:]
        # CBC模式IV必须与自定义块大小一致(16字节)
        if len(iv) != 16:
            raise ValueError("IV必须为16字节")
        self.iv = iv

    def _f_function(self, data, subkey):
        # F函数复用标准DES的核心变换(ECB模式,无填充)
        des = pyDes.des(subkey, pyDes.ECB, pad=None, padmode=None)
        return des.encrypt(data)

    def _pkcs5_pad(self, data):
        block_size = 16
        pad_len = block_size - len(data) % block_size
        return data + bytes([pad_len]) * pad_len

    def _pkcs5_unpad(self, data):
        if not data:
            return b""
        pad_len = data[-1]
        # 验证填充合法性,避免乱码
        if pad_len < 1 or pad_len > 16:
            raise ValueError("无效的PKCS5填充")
        if data[-pad_len:] != bytes([pad_len]) * pad_len:
            raise ValueError("PKCS5填充不匹配")
        return data[:-pad_len]

    def encrypt(self, plaintext):
        plain_bytes = plaintext.encode('utf-8')
        padded_data = self._pkcs5_pad(plain_bytes)
        ciphertext = b""
        prev_block = self.iv

        # 按16字节块处理
        for i in range(0, len(padded_data), 16):
            block = padded_data[i:i+16]
            # CBC模式:明文块异或上一个密文块(初始为IV)
            block_xor = bytes([b ^ pb for b, pb in zip(block, prev_block)])
            # 3轮Feistel加密
            l0, r0 = block_xor[:8], block_xor[8:]
            r1 = bytes([l ^ f for l, f in zip(l0, self._f_function(r0, self.k1))])
            l1 = r0
            r2 = bytes([l ^ f for l, f in zip(l1, self._f_function(r1, self.k2))])
            l2 = r1
            r3 = bytes([l ^ f for l, f in zip(l2, self._f_function(r2, self.k3))])
            l3 = r2
            cipher_block = l3 + r3
            ciphertext += cipher_block
            prev_block = cipher_block

        return ciphertext

    def decrypt(self, ciphertext):
        plaintext = b""
        prev_block = self.iv

        # 按16字节块处理
        for i in range(0, len(ciphertext), 16):
            cipher_block = ciphertext[i:i+16]
            # 3轮Feistel解密:逆序使用子密钥K3→K2→K1
            l3, r3 = cipher_block[:8], cipher_block[8:]
            # 轮3逆操作
            r2 = l3
            l2 = bytes([r ^ f for r, f in zip(r3, self._f_function(r2, self.k3))])
            # 轮2逆操作
            r1 = l2
            l1 = bytes([r ^ f for r, f in zip(r2, self._f_function(r1, self.k2))])
            # 轮1逆操作
            r0 = l1
            l0 = bytes([r ^ f for r, f in zip(r1, self._f_function(r0, self.k1))])
            # 得到解密后的原始块
            decrypted_block = l0 + r0
            # CBC模式:解密块异或上一个密文块(初始为IV)
            plain_block = bytes([b ^ pb for b, pb in zip(decrypted_block, prev_block)])
            plaintext += plain_block
            prev_block = cipher_block

        # 去填充并转明文
        unpadded_data = self._pkcs5_unpad(plaintext)
        return unpadded_data.decode('utf-8')

# 测试代码
if __name__ == "__main__":
    key = b"abcdefghijklmnopqrstuvwx"  # 24字节密钥
    iv = b"1234567890abcdef"          # 16字节IV
    custom_des = CustomDES(key, iv)
    plaintext = "这是一段测试明文,Custom DES加密解密验证"
    cipher = custom_des.encrypt(plaintext)
    print("加密密文(十六进制):", cipher.hex())
    decrypted_text = custom_des.decrypt(cipher)
    print("解密明文:", decrypted_text)

关键修复点

  1. 解密逻辑重构
    • 完全重写decrypt方法,不再复用encrypt逻辑。
    • Feistel解密时逆序使用子密钥(K3→K2→K1),每轮操作与加密反向:加密是R(n) = L(n-1) XOR F(R(n-1), K(n)),解密则是L(n-1) = R(n) XOR F(L(n), K(n))。
  2. CBC模式修正
    • IV长度改为16字节(与自定义块大小一致),块间异或操作覆盖完整16字节块,符合CBC模式规范。
  3. PKCS5去填充严谨性
    • 添加填充合法性校验:检查最后一个字节的数值范围(1-16),且所有填充字节值等于填充长度,避免非法数据导致的乱码。
  4. 编码一致性
    • 加密时明文统一转UTF-8字节,解密后统一从字节转UTF-8字符串,避免编码不匹配问题。

测试验证

运行测试代码后,会输出加密后的十六进制密文,以及完全还原的原始明文,解决之前的乱码问题。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 03:13:18