본문 바로가기

Programming Language/Python

SEED 암호화 - KISA 설명

KISA에서 SEED 암호화 소스코드를 제공하지만 오래전에 작성되었던 탓인지 python으로 된 파일이 없었다. 

그래서 검색으로 여러 사이트를 참고해 암호화 클래스를 작성했다. 

 

SEED 암호화란?

SEED는 128 bit의 대칭키를 이용하여 임의의 길이를 갖는 입력 메시지를 블록단위로 처리하는 128 bit 블록암호 알고리즘이다. 

 

- 대칭키 암호화 => 암호화 키와 복호화 키가 같은 암호 방식

- 128bit = 16 byte

 

 


bit | byte | hex

bit

  • 컴퓨터에서 사용되는 가장 작은 데이터 단위
  • 2진수로 0과 1을 가질 수 있다. 

byte

  • 8 bits으로 구성된다 (즉, 8 bits = 1 byte)
  • bits으로 이루어진 byte array는 2진수로 이루어진 데이터이지만 사람이 읽기 어려워 16진법이나 64진법으로 변환하여 2진수의 배열을 문자처럼 사용하기도 한다.

hex

  • 16진법으로 0~9, A~F 기호를 사용해서 숫자를 표현하는 방식이다.

ASCII

  • 64진법으로 0~9, a~z, A~F, +, / 기호를 이용해서 숫자를 표현하는 방식이다.

소스코드 설명

string 타입의 key를 byte 타입으로 변환

  • key를 2자리 수 씩 잘라서 hex 표현식으로 변환하여 배열에 넣기
  • bytes 함수를 사용해서 16진법으로 된 배열 값을 바이트 값으로 변환
def convert_key_to_byte_array(self, key):
    print("ORG KEY = {}".format(key))
    key_array = [key[i:i+2] for i in range(0, len(key), 2)]
    print("CUT BY 2 : {}".format(key_array))
    key_array = [int(val, 16) for val in key_array]
    print("KEY ARRAY = {}".format(key_array))
    key_bytes = bytes(key_array)
    print("KEY BYTES = {}".format(key_bytes))
    return key_bytes
ORG KEY = 0123456789ABCDEF0123456789ABCDEF
CUT BY 2 : ['01', '23', '45', '67', '89', 'AB', 'CD', 'EF', '01', '23', '45', '67', '89', 'AB', 'CD', 'EF']
KEY ARRAY = [1, 35, 69, 103, 137, 171, 205, 239, 1, 35, 69, 103, 137, 171, 205, 239]
KEY BYTES = b'\x01#Eg\x89\xab\xcd\xef\x01#Eg\x89\xab\xcd\xef'

 

 

string 타입의 text를 byte 타입으로 변환

  • ord 함수를 이용해서 각각의 char를 hex로 변환하여 배열에 저장
  • 16바이트에서 모자라는 자리수 만큼 특정 문자(0e)로 padding 하기
  • bytes 함수를 사용해서 16진법으로 된 배열 값을 바이트 값으로 변환
def convert_txt_to_padded_byte_array(self, txt):
    print("ORG TXT = {}".format(txt))
    txt_array = [ord(val) for val in txt]
    print("TXT ARRAY = {}".format(txt_array))
    padded_txt_array = self.pad_txt_to_sixteen_bytes(txt_array)
    padded_txt_byte_array = bytes(padded_txt_array)
    print("TXT BYTES = {}".format(padded_txt_byte_array))
    return padded_txt_byte_array

def pad_txt_to_sixteen_bytes(self, txt_array):
    padded_txt_array = [] + txt_array
    if len(txt_array) < 16:
        for _ in range(16 - len(txt_array)):
            padded_txt_array.append(int('0e', 16))
    print("PADDED TXT ARRAY = {}".format(padded_txt_array))
    return padded_txt_array
ORG TXT = 1234
TXT ARRAY = [49, 50, 51, 52]
PADDED TXT ARRAY = [49, 50, 51, 52, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14]
TXT BYTES = b'1234\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e'

 

cryptography 모듈을 이용하여 SEED 암호화

  • ECB 모드 사용
  • byte key로 cipher 설정 후 txt를 암호화
def seed_encrypt(self, key_bytes, txt_bytes):
    mode = modes.ECB()
    cipher = base.Cipher(
        algorithms.SEED(key_bytes),
        mode,
        backend
    )
    encryptor = cipher.encryptor()
    ct = encryptor.update(txt_bytes)
    ct += encryptor.finalize()
    return ct
ENCRYPTED = b'\x9c\x0b\xcb\x80K\x11\xa6\n\x93\xd4\x95\x86\xdf\x93\x98\x00'

 

base64인코딩

  • 해당 값을 API 통신을 통해 주고 받는 경우가 많은 데, 이를 위해 base64 인코딩을 적용
b64_encrypted_txt_bytes = base64.b64encode(encrypted_txt_bytes)
ENCODED BASE64 = b'nAvLgEsRpgqT1JWG35OYAA=='

 

복호화

  • 위의 순서를 반대로 진행
  • padding을 해준 값을 암호화 했기 때문에 복호화 후 unpadding 과정이 필요

 

References

[암호화 개념 및 정리] Seed 암호화 개념 정리

byte와 16진수 (Hex) String 변환

 

'Programming Language > Python' 카테고리의 다른 글

SEED 암호화 코드 - KISA  (1) 2023.01.02