Python DES ECB模式解密块边界对齐报错原因及解决方法
多余反斜杠产生原因
- 问题根源是混淆了
bytes对象的转义展示形式和实际字节内容,直接把Python打印bytes时输出的表示字符串当密文传输。 - 加密端第一次
print输出的b'.\x12\x7f...'是bytes对象的repr格式:其中\x12这类写法是Python为不可打印字节做的转义标记,实际只对应1个值为0x12的字节,不是\、x、1、2四个独立字符。 - 当你手动去掉
b''前缀把这段内容输入解密端时,输入的是纯文本字符串:所有\xNN都会被识别为4个普通字面字符,其中的反斜杠是真实存在的文本字符。对这段字符串做encode('utf8')后,每个字面反斜杠会被编码为1个字节;Python打印bytes对象时,为了区分「转义用的反斜杠」和「真实存在的反斜杠字节」,会把真实反斜杠展示为\\,这就是多出来的反斜杠的来源。 - 经过错误转换后,原本16字节的密文会膨胀到几十字节长,完全不满足DES ECB模式要求的密文长度为8字节整数倍的规则,因此抛出块边界对齐错误。
修复方案
核心原则:加密产生的二进制密文不能直接通过打印repr的方式跨进程传输,必须先将二进制密文编码为十六进制、Base64这类纯可打印字符格式;解密端收到文本后先解码还原为原始二进制字节,再执行解密操作。
以下是拆分后可独立运行的加密、解密端代码:
加密端代码
from Crypto.Cipher import DES import binascii key = b'abcdefgh' def pad(text: bytes) -> bytes: while len(text) % 8 != 0: text += b' ' return text if __name__ == "__main__": des = DES.new(key, DES.MODE_ECB) plaintext = b'Secret text' padded_text = pad(plaintext) encrypted_bytes = des.encrypt(padded_text) # 将二进制密文转为十六进制可打印字符串输出,无特殊转义字符,可直接复制 cipher_text = binascii.hexlify(encrypted_bytes).decode("ascii") print(cipher_text)
解密端代码
from Crypto.Cipher import DES import binascii key = b'abcdefgh' if __name__ == "__main__": des = DES.new(key, DES.MODE_ECB) # 接收输入的十六进制密文 input_cipher = input().strip() # 将十六进制字符串还原为原始二进制密文 encrypted_bytes = binascii.unhexlify(input_cipher) # 解密后去掉填充的空格 plaintext = des.decrypt(encrypted_bytes).rstrip(b' ') print(plaintext)
运行验证:
- 运行加密端,会输出类似
2e127fcfad2ba90cc4de0515ef7f16a0的纯文本字符串 - 将该字符串直接输入解密端,即可正常解密得到原始明文
b'Secret text',不会出现转义错误或块对齐异常。
内容的提问来源于stack exchange,提问作者De Solid Clay
相关产品推荐
相关产品推荐

