주상 전치 암호는 특정 개수 열로 평문 문장을 배열한 후, 열 방향으로 문장을 읽어 암호문을 구성하는 암호화 방법이다.

여기서 중요한 것은 읽어 들이는 열의 순서

 

만약 암호키가 'BRAIN'인 경우 암호크 크기는 5이므로 평문 배열은 5열로 구성하고 'B','R','A','I','N'의 상대적인 순서는 2,5,1,3,4이다.

 

B  R  A  I  N

2  5  1  3  4

A  B  C  D  E

F  G  H   I  J

K  L  M  N  O

P  Q  R  S  T

 

각 열에 배열된 문자 개수는 4개이다. 이 숫자를 앞으로 암호 블록 크기라고 부른다.

배열된 문장의 각 열을 읽는 순서는 1열부터 5열까지 각각 2,5,1,3,4이므로, 이 순서로 각 열을 읽어 암호문을 만들면 'CHMR AFKP DINS EJOT BGLQ'로 암호화가 된다. (당연히 생성된 암호문에서 공백을 제거한 후가 최종 암호문)

 

ENC = 0
DEC = 1

def parseKey(key):
    key = key.upper()
    tmp = []

    for i, k in enumerate(key):
        tmp.append((i, k))

    tmp = sorted(tmp, key = lambda x: x[1])

    enc_table = {}
    dec_table = {}

    for i, r in enumerate(tmp):
        enc_table[r[0]] = i
        dec_table[i] = r[0]

    return enc_table, dec_table


def transposition(msg, key, mode):
    msgsize = len(msg)
    keysize = len(key)
    ret = ''

    filler = '' 
    if msgsize%keysize != 0:        #보다 쉬운 프로그래밍을 위해 평문이 키크기의 배수가 아닐시 배수가 되도록 평문의 끝에 문자 '0'으로 채우기
        filler = '0'*(keysize - msgsize%keysize)

    msg = msg.upper()   
    msg += filler

    enc_table, dec_table = parseKey(key)

    if mode == ENC:
        table = enc_table
    else:
        table = dec_table
    
    if mode == ENC:
        buf = ['']*keysize
        for i, c in enumerate(msg):
            col = i%keysize
            index = table[col]
            buf[index] += c
        
        for text in buf:
            ret += text
      
    
    else:
        blocksize = int(msgsize/keysize)
        buf = ['']*keysize
        pos = 0
        for i in range(keysize):
            text = msg[pos:pos+blocksize]   #암호문 블록크기만 큼 자름 [0:4], [4:8],..
            index = table[i]
            buf[index] += text
            pos += blocksize
        
        for i in range(blocksize):
            for j in range(keysize):
                if buf[j][i] != '0':
                    ret += buf[j][i]
    return ret


def main():
    key = 'BRAIN'   
    msg = 'TREASUREBOXISBURRIEDATTWOHUNDREDFEETTONORTHEASTAWAYFROMYOURHOME'
    print('Original:\t%s' %msg.upper()) 

    ciphertext = transposition(msg, key, ENC)
    print('Ciphered:\t%s' %ciphertext)

    deciphertext = transposition(ciphertext, key, DEC)
    print('Deciphered:\t%s' %deciphertext)


if __name__ == '__main__':
    main()

 

 

출처: 화이트 해커를 위한 암호화 해킹

+ Recent posts