单字节XOR密码(python)

时间:2017-01-24 03:23:09

标签: python string python-3.x byte

这是我正在参加的现代密码学课程。

挑战是密码挑战3:单字节XOR密码,我正在尝试使用python 3来帮助完成此任务。

我知道我应该对字符串进行异或并转换为英语。十六进制字符串是" 1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736"转换为" 806748453371902409051174291875458592743800337585421566549206796642836053682239286"十进制形式。

我对多个十六进制字节组合(2个十六进制数字)进行XOR'这个,但我不知道如何将其转换为英语。这只是蛮力和有根据的猜测吗?

我知道ETAOIN SHRDLU,但这并没有真正有用。

感谢您的时间和帮助。

增加: 另外,我尝试了挑战#4,但这段代码似乎不起作用。但它确实适用于挑战#3,所以我很困惑。

Challenge #3 Challenge #4

3 个答案:

答案 0 :(得分:4)

建立@fattru的答案,但只显示空格字符最多的解码字符串:

>>> encoded = '1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736'
>>> import binascii
>>> nums = binascii.unhexlify(encoded)
>>> strings = (''.join(chr(num ^ key) for num in nums) for key in range(256))
>>> max(strings, key=lambda s: s.count(' '))
"Cooking MC's like a pound of bacon"

您可以使用ETAOIN SHRDLU("英语中最常用的12个字母的频率的大致顺序")而不是计算空格,但它可以使用the challenge。这里没有必要。

顺便说一下,如果你链接到{{3}},我认为它会很好。

编辑:或者,您可以尝试找到密钥(或一些最有前途的密钥),然后只使用该密钥(或那些几个密钥)进行解码。例如,假设计算空格将决定胜利者:

>>> encoded = '1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736'
>>> import binascii
>>> nums = binascii.unhexlify(encoded)
>>> key = max(nums, key=nums.count) ^ ord(' ')
>>> ''.join(chr(num ^ key) for num in nums)
"Cooking MC's like a pound of bacon"

这甚至可以很容易地手工完成(虽然挑战告诉你不要这样做)。

答案 1 :(得分:3)

您可以使用binascii.hexlifybinascii.unhexlify将字节字符串转换为十六进制,反之亦然:

>>> import binascii
>>> binascii.hexlify(b'HELLO')  # to Hex
b'48454c4c4f'
>>> binascii.unhexlify('48454c4c4f')  # from Hex
b'HELLO'

使用str.isprintable,您可以过滤掉不可打印的候选人:

>>> 'abcd'.isprintable()
True
>>> '\x00'.isprintable()
False
>>> '\x7f'.isprintable()
False
import binascii

encoded = binascii.unhexlify('1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736')
for xor_key in range(256):
    decoded = ''.join(chr(b ^ xor_key) for b in encoded)
    if decoded.isprintable():
        print(xor_key, decoded)

答案 2 :(得分:0)

通过观察,您可以在编码字符串中找到“ 3737”,因此对于英语单词来说,它可以是“ e”,“ E”,“ o”,“ O”,“ r”,“ R”吗? 使用逆向工程,XOR结果显示“ R”,“ r”,“ X”,“ x”,“ E”,“ e”作为电位键。 在尝试了这些电位键之后,您将获得“ X”为键;-)