SECCON -Vigenere3d

题目如下:

Vigenere3d
----- Vigenere3d.py
import sys
def _l(idx, s):
    return s[idx:] + s[:idx]
def main(p, k1, k2):
    s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz_{}"
    t = [[_l((i+j) % len(s), s) for j in range(len(s))] for i in range(len(s))]
    i1 = 0
    i2 = 0
    c = ""
    for a in p:
        c += t[s.find(a)][s.find(k1[i1])][s.find(k2[i2])]
        i1 = (i1 + 1) % len(k1)
        i2 = (i2 + 1) % len(k2)
    return c
print main(sys.argv[1], sys.argv[2], sys.argv[2][::-1])
-----
$ python Vigenere3d.py SECCON{**************************} **************
POR4dnyTLHBfwbxAAZhe}}ocZR3Cxcftw9

首先题目生成一个三维数组的密码本,就好比谍战片的流密码本;
加密的过程:

  • (1):首先查找在s中的位置,作为数组的第一维
  • (2):取 第二参数(子字符串)一位,作为数组的第二维,依次相模。
  • (3):取第三个参数的一位,作为数组的第三维。(这里和上一步骤一样,但是取的方法是从后往前取值)
  for a in p:
        c += t[s.find(a)][s.find(k1[i1])][s.find(k2[i2])]
        i1 = (i1 + 1) % len(k1)
        i2 = (i2 + 1) % len(k2)
    return c
print main(sys.argv[1], sys.argv[2], sys.argv[2][::-1])

这里有个细节说一下:
我一直不明白一个问题,这个题好像对解密的key值的位数,并没有做说明。

$ python Vigenere3d.py SECCON{**************************} **************
POR4dnyTLHBfwbxAAZhe}}ocZR3Cxcftw9

从这里看到第二个参数的位数为14,固推断key位数为14

解密过程:

$ python Vigenere3d.py SECCON{**************************} **************
POR4dnyTLHBfwbxAAZhe}}ocZR3Cxcftw9
  • 1: 对已知部分“SECCON{”进行加密,加密的所使密钥依次使用s串中字符。
  • 2:加密后的字符串依次和题目中所给出的的字符串 ciphertext进行匹配;匹配成功,将加密使用的字符写入key中。
 res = encrypt(known_prefix, key, key[::-1])
            if res[pos] == ciphertex[pos]:
                final_key[pos] = c
                final_key[13 - pos] = c
                print "".join(final_key)
计算k值
  • 3: 参数2、参数3也就是加密所使用的k1、k2.互为倒数。
print main(sys.argv[1], sys.argv[2], sys.argv[2][::-1])

设置一个14位的字符串,写入时。使用如下方式即可:(在第一位 写一个,在最后一位写一个)

partial_candidate_key[pos] = c
 partial_candidate_key[13 - pos] = c

得到解密k,及时解密。
完整脚本如下:

s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz_{}"


def _l(idx, s):
    return s[idx:] + s[:idx]


def decrypt(ct, k1, k2):
    s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz_{}"
    t = [[_l((i + j) % len(s), s) for j in range(len(s))] for i in range(len(s))]
    i1 = 0
    i2 = 0
    decrypted = ""
    for a in ct:
        for c in s:
            if t[s.find(c)][s.find(k1[i1])][s.find(k2[i2])] == a:
                decrypted += c
                break
        i1 = (i1 + 1) % len(k1)
        i2 = (i2 + 1) % len(k2)
    return decrypted


def encrypt(p, k1, k2):
    t = [[_l((i + j) % len(s), s) for j in range(len(s))] for i in range(len(s))]
    i1 = 0
    i2 = 0
    c = ""
    for a in p:
        c += t[s.find(a)][s.find(k1[i1])][s.find(k2[i2])]
        i1 = (i1 + 1) % len(k1)
        i2 = (i2 + 1) % len(k2)
    return c


def recover_key(known_prefix, ciphertex):
    final_key = ['*'] * 14
    for pos in range(7):
        for c in s:
            partial_candidate_key = ['*'] * 14
            partial_candidate_key[pos] = c
            partial_candidate_key[13 - pos] = c
            key = "".join(partial_candidate_key)
            res = encrypt(known_prefix, key, key[::-1])
            if res[pos] == ciphertex[pos]:
                final_key[pos] = c
                final_key[13 - pos] = c
                print "".join(final_key)
    return "".join(final_key)


def main():
    ciphertext = "POR4dnyTLHBfwbxAAZhe}}ocZR3Cxcftw9"
    key = recover_key("SECCON{", ciphertext)
    flag = decrypt(ciphertext, key, key[::-1])
    print(flag)


main()

你可能感兴趣的:(SECCON -Vigenere3d)