Skip to content

Instantly share code, notes, and snippets.

@20chan
Last active June 14, 2019 14:55
Show Gist options
  • Save 20chan/d15b147012b9f0fe4a538b407e788484 to your computer and use it in GitHub Desktop.
Save 20chan/d15b147012b9f0fe4a538b407e788484 to your computer and use it in GitHub Desktop.
국가암호공모전 롸업

프로그램에서 A를 25번 입력하면 UIYOAUOIOEIAYEUYOIEYEAUYA 이 나온다. 이 값을 EncVowel 테이블과 비교하여 찾아보면, 초기 vowel_position의 값은 8임을 알 수 있다. 이때의 EncVowel 테이블의 값은 {6, 3, 5, 2, 1, 4} 이다.

프로그램을 실행하고 처음 A, E, I, O, U, Y 의 모음을 입력하여 나오는 값은 각각 U, E, I, Y, O, A 이다. 코드의 ct_num 에 해당되는 모음의 숫자 값은 각각 4, 1, 2, 5, 3, 0 이다. 그러면 테이블과 비교하여 이 값이 나오기 위한 인덱스 (perm_num) 값은 각각 2, 3, 1, 0, 5, 4 이다. 그렇다면 PermVowel 의 값은 {3, 4, 2, 1, 6, 5} 임을 알 수 있다.

같은 방식으로 자음도 구할 수 있다. 첫번째 글자로 자음들 B, C, D, ..., Z의 결과값은 JWHZCXVLGSBQRMPFKNTD 이고 두번째 글자로 자음들의 결과값은 MFKXVPZTHDLNGJWBSCQR 이다. 이때 세개의 테이블 중 첫번째 테이블만이 인덱스가 변했을 경우와 두번째 테이블과 첫번째 테이블 둘다 인덱스가 변했을 경우가 있지만 일단 첫번째 경우만 생각해주고 안되면 두번째 케이스를 생각해 보는 것으로 한다.

EncCon1의 테이블 중에서 위의 두 결과값을 비교하여 각 글자에 해당하는 인덱스가 똑같이 움직인 테이블을 찾으면 3번째 2,19,12,... 가 처음, 4번째 14,9,1,...가 두번째 테이블임을 알 수 있다. 그렇다면 cons1_position의 값은 2가 된다. 같은 방법으로 cons2_position 값도 찾을 수 있다. 26번째 글자로 자음들이 들어간 결과값은 첫번째 글자로 자음들이 들어간 결과값에 비해 첫 테이블은 그대로이고 두번째 테이블만 한번 돌았거나, 세번째 테이블까지 돌았을 수 있지만 역시 일단 첫번째 경우로 생각해준다. 일단 두번째 테이블으로 들어가는 인덱스 값인 첫번째 테이블의 2번째 2, 19, 12, .. 순으로 자음들을 정렬해주면 VBQHSNXPTWMDJRKZFLCG 이고 이 자음들이 첫번째 글자로, 26번째 글자로 프로그램에 들어간 결과값을 구해주면 각각 KJRXPBTQFNSHVMLDZGWCCPTZSFDRWBGLMXKJQVNH 이다. 똑같이 인덱스를 비교해주면 두번째 테이블의 첫번째와 두번째가 사용됐음을 알 수 있다.그러므로 cons2_position의 값은 0이 된다. 같은 방법으로 cons3_position의 값도 구해줄 수 있지만 25가지 정도는 일일히 해보기에 충분하여 일일히 해보면 1임을 알 수 있다.

아래는 사용했던 파이썬 스크립트 코드이다.

import subprocess

vowels = ['A', 'E', 'I', 'O', 'U', 'Y']
alphs = [chr(a) for a in range(ord('A'), ord('Z') + 1) if not chr(a) in vowels]
# alphs = 'VBQHSNXPTWMDJRKZFLCG'
def get(s):
    proc = subprocess.Popen(
        'violet_backup.exe', stdout=subprocess.PIPE,
        stdin=subprocess.PIPE
    )
    proc.stdin.write(s.encode())
    proc.stdin.close()

    result = proc.stdout.read()
    proc.wait()
    return result.decode()
res = [get(c*26) for c in alphs]

print(''.join(i[0] for i in res))
print(''.join(i[25] for i in res))
  1. 구현했음
910628-1891234
177BD4=437=224C29AB838812DCB
910629-1891235
177BD4=437=424C29AB838812DCB
910630-1891236
177BD4=4379224C29AB838812DD1
951211-1891237
177BD69A379424C29AB838812DD1
951211-1891238
177BD69A379424C29AB838812DCB
951211-2891238
177BD69A379424C49AB838812DCB
951211-2891240
177BD69A379424C49AB838812DCB
991125-2891241
177BD69=379A24C49AB838812DCB
991126-2891241
177BD69=379=24C49AB838812DCB
991126-2891242
177BD69=379=24C49AB838812DD1
  1. 문제점/방안

맨 오른쪽 비트만 차이나는 두 입력 값에 대해서 고정된 Nonce, Counter 값을 사용하여 나오는 암호 블럭도 맨 오른쪽 비트만 차이난다. 그래서 응용함수를 계산하면 다른 입력값에 대해 같은 출력값이 나올 수 있다.

이를 위해서는 Nonce 벡터를 랜덤화하고 암호의 처음부분에 삽입하여 데이터베이스의 문자열 길이를 늘려야 한다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment