--- lang: ja-jp breaks: true --- Vigenere === ## 問題概要 ### ジャンル crypto ### 点数 100 points ### 問題文 Vigenere ``` k: ???????????? p: SECCON{???????????????????????????????????} c: LMIG}RPEDOEEWKJIQIWKJWMNDTSR}TFVUFWYOCBAJBQ |ABCDEFGHIJKLMNOPQRSTUVWXYZ{} -+---------------------------- A|ABCDEFGHIJKLMNOPQRSTUVWXYZ{} B|BCDEFGHIJKLMNOPQRSTUVWXYZ{}A C|CDEFGHIJKLMNOPQRSTUVWXYZ{}AB D|DEFGHIJKLMNOPQRSTUVWXYZ{}ABC E|EFGHIJKLMNOPQRSTUVWXYZ{}ABCD F|FGHIJKLMNOPQRSTUVWXYZ{}ABCDE G|GHIJKLMNOPQRSTUVWXYZ{}ABCDEF H|HIJKLMNOPQRSTUVWXYZ{}ABCDEFG I|IJKLMNOPQRSTUVWXYZ{}ABCDEFGH J|JKLMNOPQRSTUVWXYZ{}ABCDEFGHI K|KLMNOPQRSTUVWXYZ{}ABCDEFGHIJ L|LMNOPQRSTUVWXYZ{}ABCDEFGHIJK M|MNOPQRSTUVWXYZ{}ABCDEFGHIJKL N|NOPQRSTUVWXYZ{}ABCDEFGHIJKLM O|OPQRSTUVWXYZ{}ABCDEFGHIJKLMN P|PQRSTUVWXYZ{}ABCDEFGHIJKLMNO Q|QRSTUVWXYZ{}ABCDEFGHIJKLMNOP R|RSTUVWXYZ{}ABCDEFGHIJKLMNOPQ S|STUVWXYZ{}ABCDEFGHIJKLMNOPQR T|TUVWXYZ{}ABCDEFGHIJKLMNOPQRS U|UVWXYZ{}ABCDEFGHIJKLMNOPQRST V|VWXYZ{}ABCDEFGHIJKLMNOPQRSTU W|WXYZ{}ABCDEFGHIJKLMNOPQRSTUV X|XYZ{}ABCDEFGHIJKLMNOPQRSTUVW Y|YZ{}ABCDEFGHIJKLMNOPQRSTUVWX Z|Z{}ABCDEFGHIJKLMNOPQRSTUVWXY {|{}ABCDEFGHIJKLMNOPQRSTUVWXYZ }|}ABCDEFGHIJKLMNOPQRSTUVWXYZ{ ``` ### フラグ SECCON{ABABABCDEDEFGHIJJKLMNOPQRSTTUVWXYYZ} ### 挑戦者 tkmru idzuna ## 解法 cipherとplain textを見比べると,key冒頭が`VIGENER`であることがわかる. とりあえずkeyを`VIGENERAAAAA`と仮定して復号すると,flagの中身は,アルファベットを順番に並べて一部を繰り返した文字列であるらしいことがわかる. あとは勘でkeyを推測したらできた. ## 議論 [ヴィジュネル暗号 - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%B4%E3%82%A3%E3%82%B8%E3%83%A5%E3%83%8D%E3%83%AB%E6%9A%97%E5%8F%B7) しほくんの参考になるかな http://elliptic-shiho.hatenablog.com/entry/2015/11/12/041637 Keyが`VIGENERECODE`で長さが12。(12元の変数) 平文が43文字。 書きかけのやつ ```python= #!/usr/bin/env python2.7 # coding: UTF-8 c = 'LMIG}RPEDOEEWKJIQIWKJWMNDTSR}TFVUFWYOCBAJBQ' p = 'SECCON{' #key_offset = [21, 8, 6, 4, 13, 4, 17, 4, 21, 8, 6, 4] #VIGENEREVIGEのAからのoffset #key_offset = [21, 8, 6, 4, 13, 4, 17, 4] # VIGENEREのAからのoffset key_offset = [21, 8, 6, 4, 13, 4, 17] # VIGENERのAからのoffset table = {'A': 'ABCDEFGHIJKLMNOPQRSTUVWXYZ{}', 'B': 'BCDEFGHIJKLMNOPQRSTUVWXYZ{}A', 'C': 'CDEFGHIJKLMNOPQRSTUVWXYZ{}AB', 'D': 'DEFGHIJKLMNOPQRSTUVWXYZ{}ABC', 'E': 'EFGHIJKLMNOPQRSTUVWXYZ{}ABCD', 'F': 'FGHIJKLMNOPQRSTUVWXYZ{}ABCDE', 'G': 'GHIJKLMNOPQRSTUVWXYZ{}ABCDEF', 'H': 'HIJKLMNOPQRSTUVWXYZ{}ABCDEFG', 'I': 'IJKLMNOPQRSTUVWXYZ{}ABCDEFGH', 'J': 'JKLMNOPQRSTUVWXYZ{}ABCDEFGHI', 'K': 'KLMNOPQRSTUVWXYZ{}ABCDEFGHIJ', 'L': 'LMNOPQRSTUVWXYZ{}ABCDEFGHIJK', 'M': 'MNOPQRSTUVWXYZ{}ABCDEFGHIJKL', 'N': 'NOPQRSTUVWXYZ{}ABCDEFGHIJKLM', 'O': 'OPQRSTUVWXYZ{}ABCDEFGHIJKLMN', 'P': 'PQRSTUVWXYZ{}ABCDEFGHIJKLMNO', 'Q': 'QRSTUVWXYZ{}ABCDEFGHIJKLMNOP', 'R': 'RSTUVWXYZ{}ABCDEFGHIJKLMNOPQ', 'S': 'STUVWXYZ{}ABCDEFGHIJKLMNOPQR', 'T': 'TUVWXYZ{}ABCDEFGHIJKLMNOPQRS', 'U': 'UVWXYZ{}ABCDEFGHIJKLMNOPQRST', 'V': 'VWXYZ{}ABCDEFGHIJKLMNOPQRSTU', 'W': 'WXYZ{}ABCDEFGHIJKLMNOPQRSTUV', 'X': 'XYZ{}ABCDEFGHIJKLMNOPQRSTUVW', 'Y': 'YZ{}ABCDEFGHIJKLMNOPQRSTUVWX', 'Z': 'Z{}ABCDEFGHIJKLMNOPQRSTUVWXY', '{': '{}ABCDEFGHIJKLMNOPQRSTUVWXYZ', '}': '}ABCDEFGHIJKLMNOPQRSTUVWXYZ{'} ''' key冒頭復号(VIGENERになった) print chr(0x41 + table['S'].find(c[0])), table['S'].find(c[0]) print chr(0x41 + table['E'].find(c[1])), table['E'].find(c[1]) print chr(0x41 + table['C'].find(c[2])), table['C'].find(c[2]) print chr(0x41 + table['C'].find(c[3])), table['C'].find(c[3]) print chr(0x41 + table['O'].find(c[4])), table['O'].find(c[4]) print chr(0x41 + table['N'].find(c[5])), table['N'].find(c[5]) print chr(0x41 + table['{'].find(c[6])), table['{'].find(c[6]) ''' flag = '' for i, v in enumerate(c): ki = key_offset[i % len(key_offset)] for table_key in table: if table[table_key][ki] == v: print table_key flag += table_key print flag ``` SECCON{_____BCDEDEF_____KLMNOPQ_____VWXYYZ}