0

在下面的代码中,我试图解密一条加密消息,给定两条使用相同密钥(两次密码)加密的消息。该代码也可以按我的意愿工作,直到我尝试将十六进制字符串打印为 ascii 的最后一行。

我得到错误:

    print result.decode('hex')
  File "/usr/lib/python2.7/encodings/hex_codec.py", line 42, in hex_decode
    output = binascii.a2b_hex(input)
TypeError: Non-hexadecimal digit found

导致错误的十六进制字符串是:

ab51e67kba7<4:72fd`d

其中有一些非十六进制字符。我不确定为什么它里面有非十六进制。或者从这里去哪里。

这是完整的代码:

# Messages
m1 = "31aa4573aa487946aa15"
m2 = "32510ba9babebbbefd00"

# Key
k = "6b6bdfa4rqggrgwereff"

guess = 'aa'
#guess = guess.encode('hex')
result = ''


def strxor(a, b):     # xor two strings of different lengths
    if len(a) > len(b):
        return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a[:len(b)], b)])
    else:
        return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b[:len(a)])])

# Make cipher texts
c1 = strxor(m1,k)
c2 = strxor(m2,k)

# xor of the two messages   
m1m2 = strxor(c1,c2)

# loop through each bit of the m1m2 message and xor against a test char or string
# see if any of the output makes sense
for e in range(0, len(m1), 2):
    subString = m1m2[e:e+2]
    try:
        result = result + "".join( strxor(subString, guess))
    except exception: 
        pass

#print hex and ascii results
print result
print result.decode('hex')
4

2 回答 2

1

如果我理解正确,您的意图是strxor遍历两个字符串,将每个字符转换为 0-15 范围内的数字,将每个字符串中的相应字符异或,然后将结果转换回字符并返回结果字符串。我不认为这样strxor做 - 例如,ord('6')不是 6,而是 54(字符的 ASCII 值)。我怀疑这就是为什么您在输入中得到非十六进制字符的原因。

而不是chr(ord(x) ^ ord(y)),我认为你想要的是:

def toHexNum(c):
    n = ord(c)
    if n >= ord('0') and n <= ord('9'):
        return n - ord('0')
    elif n >= ord('A') and n <= ord('F'):
        return n - ord('A') + 10
    elif n >= ord('a') and n <= ord('f'):
        return n - ord('a') + 10
    else:
        return None

def fromHexNum(n):
    chars = "0123456789abcdef"
    return chars[n]

def strxor(a, b):     # xor two strings of different lengths
    if len(a) > len(b):
        return "".join([fromHexNum(toHexNum(x) ^ toHexNum(y)) for (x, y) in zip(a[:len(b)], b)])
    else:
        return "".join([fromHexNum(toHexNum(x) ^ toHexNum(y)) for (x, y) in zip(a, b[:len(a)])])

可能有一种更简洁的方法可以做到这一点,但我似乎找不到它——也许对 Python 库的了解比我强的人可以加入该笔记。

于 2013-09-13T03:31:38.067 回答
1

倒带一点,看看里面有什么c1

也就是说,通过

# Messages
m1 = "31aa4573aa487946aa15"
m2 = "32510ba9babebbbefd00"

# Key
k = "6b6bdfa4rqggrgwereff"

guess = 'aa'
#guess = guess.encode('hex')
result = ''


def strxor(a, b):     # xor two strings of different lengths
    if len(a) > len(b):
        return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a[:len(b)], b)])
    else:
        return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b[:len(a)])])

# Make cipher texts
c1 = strxor(m1,k)

c1'\x05SW\x03PSV\x07\x13\x10S_E^CS\x13\x04WS'这种情况下。

m1k被异或时,两个ascii 十六进制数字字符串已被异或。结果肯定会超出您的预期。

事实上,这里是通过异或这些数字最终得到的整个字符集:

In[0]: set((chr(ord(i)^ord(j)) for j in "abcdef0123456789" for i in "abcdef0123456789"))

Out[0]: {'\x00',
         '\x01',
         '\x02',
         '\x03',
         '\x04',
         '\x05',
         '\x06',
         '\x07',
         '\x08',
         '\t',
         '\n',
         '\x0b',
         '\x0c',
         '\r',
         '\x0e',
         '\x0f',
         'P',
         'Q',
         'R',
         'S',
         'T',
         'U',
         'V',
         'W',
         'X',
         'Y',
         'Z',
         '[',
         '\\',
         ']',
         '^',
         '_'}

在旁注中,请告诉我这是为了课堂作业还是只是为了好玩。你不应该像这样滚动自己的加密货币。

于 2013-09-13T03:16:23.570 回答