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
'Programming Language > Python' 카테고리의 다른 글
SEED 암호화 코드 - KISA (1) | 2023.01.02 |
---|