0

以下のコードでは、同じキー (2 タイム パッド) で暗号化された 2 つのメッセージを指定して、暗号化されたメッセージを復号化しようとしています。コードは、16進文字列を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

エラーの原因となっている 16 進文字列は次のとおりです。

ab51e67kba7<4:72fd`d

その中に非16進文字が含まれています。非六角が含まれている理由がわかりません。または、ここからどこへ行くか。

完全なコードは次のとおりです。

# 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 の範囲の数値に変換し、各文字列の対応する文字を XOR し、結果を文字に変換して結果の文字列を返すことです。私はそれがそうしているとは思わないstrxor- 例えば、ord('6')6 ではなく、むしろ 54 (文字の ASCII 値) である。これが、入力に16進数以外の文字が含まれている理由だと思います。

の代わりに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が xor されると、ASCII 16 進数の 2 つの文字列がxorれます。結果は間違いなくあなたが期待している範囲から外れます。

実際、これらの数字だけを xor することで最終的に得られる文字のセット全体を次に示します。

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 に答える