11

我正在使用 PyCrypto,我似乎成功地解密了我的数据。但是,我收到的字符串似乎表现得很奇怪:

...
plaintext = cipher.decrypt(encrypted)
print 'plaintext length is %u' % len(plaintext)
print 'plaintext: %s' % plaintext
print 'plaintext is "%s"' % plaintext

明文有我期望的字符串(“POEorOPE”),但输出看起来很奇怪:

plaintext length is 16
plaintext: POEorOPE
plaintext is ""OEorOPE

为什么第三个打印语句中的字符串似乎占用了零空间,因此它的第一个字符被我认为是结束引号的内容覆盖了?我现在以明文形式存储的内容是否还有其他事情发生?

编辑:

感谢您的评论,我知道发生了什么。(虽然我不知道为什么我的字符串中有退格字符。)

print repr(plaintext)

'POEorOPE\x08\x08\x08\x08\x08\x08\x08\x08'
4

2 回答 2

3

一些(非常老的)软件使用了一个巧妙的技巧,通过“加倍一个字符”来模拟粗体文本:打印字符,退格,然后再次打印字符。复制会产生更大、更暗的字形。

您的字符串应该是 8 个字符,但显示的 len 为 16。那是因为添加了 8 个 unicode 代码点(“\x08”)(可能作为解密过程的一部分)。

unicode 点“\x08”确实代表退格。为了说明这些只是无意义的 unicode 点:

>>> u = u'POEorOPE\x08\x08\x08\x08\x08\x08\x08\x08'
>>> print u.encode()
POEorOPE
于 2013-03-24T22:42:19.320 回答
1

原来这些退格字符是Perl 的 Crypt::CBC 模块添加的字节填充。在这种特殊情况下,填充字节都是“08”,表示有 8 个字节的填充应该被删除。PyCrypto 在解密或加密期间不处理填充。我可以像这样剥离填充字节:

text_bytes = bytearray(plaintext,'utf-8')
num_bytes_padding = text_bytes[len(text_bytes) - 1]
text_bytes[-1 * num_bytes_padding:] = []
plaintext = text_bytes.decode('utf-8') 
于 2013-03-25T20:32:23.453 回答