Break Repeated Key XOR

时间:2015-08-26 15:58:16

标签: python python-2.7 cryptography hex xor

我正在研究matasano加密挑战here

但是我在挑战6中遇到了困难,这可以很好地概述所需的步骤。我必须尝试找到密钥大小,将密文大小分解为密钥大小长度块,转置块以获得与密钥大小的每个字节对应的块,然后将转置块解析为好像它们是单个字符XOR密码。从概念上讲,这一切都是有道理的。但是对python来说还是个新手,我的程序并没有按照需要运行。我已经完成了,看起来下面的汉明距离函数就像它应该的那样,并且分解十六进制编码的文本也可以。但到了调用get_max_single_char_xor的时候,我收到了一堆难以理解的文字。也许第二双眼睛可以帮助我弄清楚我做错了什么,或者为什么它没有给我可读的输出。

查看以下代码:

def calc_hamming_dist(str1, str2):
  diff = 0
  val = int(str1, 16) ^ int(str2, 16)
  while(val != 0):
    diff += 1
    val &= val-1
  return diff

def break_repeating_key_XOR(hex_text):
  keysize = 2
  key_hamming_val = []
  hex_len = len(hex_text)
  print 'hex_len: ' + str(hex_len)

  for b in xrange(2, 40):
    hamming_vals = 0
    pos = 0
    counter = 0
    while(pos + 2*keysize <= hex_len):
        key1 = hex_text[pos:pos+keysize]
        pos += keysize
        key2 = hex_text[pos:pos+keysize]
        pos += keysize
        hamming_vals += calc_hamming_dist(key1, key2)
        counter += 1
    hamming_vals = float(hamming_vals/float(counter))
    key_hamming_val.append((float(hamming_vals/float(keysize)), keysize))
    keysize += 1

  print 'hamming_val length: ' + str(len(key_hamming_val))
  key_hamming_val.sort()
  for a in xrange(2, 38):
    blocks1 = []
    blocks2 = []
    count = 0
    key = ''

    min_hamming, keysize_guess = key_hamming_val[a]
    #for x in range(keysize_guess):
        #blocks2.append('')
    while count <= hex_len:
        blocks1.append(hex_text[count:count+keysize_guess])
        count += keysize_guess
    print str(min_hamming) + ', ' + str(keysize_guess)
    zzz = 0
    for x in blocks1:
        zzz += len(x)
    #print blocks1

    for x in range(keysize_guess):
        count = 0
        in_str = ''
        while count < len(blocks1):
            try:
                in_str += (blocks1[count])[x]
            except IndexError:
                break
            count += 1
        #print in_str
        blocks2.insert(x, in_str)
    zzz = 0
    for x in blocks2:
        zzz += len(x)
    #print blocks2

    for y in blocks2:
        if (len(y) % 2) != 0:
            y = '0' + y
        (score, words, key_guess) = get_max_single_char_xor(y)
        #print ' ' + str(key_guess)
        key += chr(key_guess)

    print key + ' (' + str(len(key)) + ')'

一些注意事项:传入的hex_text是一串已编码的十六进制值。以下是另一个模块中调用的一些函数:

def score_plaintext(s, val):
  letters = filter(lambda val: 'a'<=val<='z' or 'A'<=val<='Z', s)
  #letters = filter(lambda  val: ' '<=val<='~', s)
  return float(len(letters)) / len(s)

def get_max_single_char_xor(val):
  res = []
  for i in range(256):
    chrs = [chr(ord(s) ^ i) for s in val.decode('hex')]
    res.append([score_plaintext(chrs, val), ''.join(chrs), i])

ret = sorted(res, key=lambda res: res[0], reverse=True)
  for i in ret:
    (score, words, key) = i
    if all(c in string.printable for c in words):
        return i
  return max(res, key=lambda s: s[0])

基于其他一些挑战,上述两个功能应该可以正常运行。但我无法确定。

有人发现此代码存在任何问题吗?

0 个答案:

没有答案