在下面的代码中,我试图解密加密的消息,给出两条用相同密钥加密的消息(两次打击垫)。代码按照我的要求工作,直到最后一行我尝试打印出十六进制字符串为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')
答案 0 :(得分: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'
。
当m1
和k
被xor'ed时,两个 ascii十六进制数字字符串已被xored。结果肯定会超出您期望的范围。
事实上,这里只是通过xoring这些数字来结束整个字符集:
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',
'[',
'\\',
']',
'^',
'_'}
另一方面,请告诉我这是课堂作业或只是为了好玩。你不应该像这样滚动你自己的加密。
答案 1 :(得分: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库的了解比我强大的人可以在这个注释中插入。