"SEED"의 두 판 사이의 차이
choywoongkyu (토론 | 기여) |
(→S-Box) |
||
(사용자 4명의 중간 판 34개는 보이지 않습니다) | |||
1번째 줄: | 1번째 줄: | ||
− | ''' | + | '''SEED''' 또는 '''시드 블록 암호 알고리즘'''<!--시드블록암호 알고리즘-->은 [[전자상거래]], 금융, [[무선통신]] 등에서 전송되는 개인정보와 같은 중요한 정보를 보호하기 위해, 1999년 2월 [[한국인터넷진흥원]]과 국내 암호전문가들이 순수 국내기술로 개발한 128비트 및 256비트 대칭 키 블록의 암호 [[알고리즘]]이다. 미국에서 수출하는 [[웹브라우저]] 보안의 수준이 40비트로 제한함으로써 128비트 보안을 위해서 자국에서 개발한 별도의 알고리즘이다. |
− | ==역사== | + | == 개요 == |
− | *1999년 2월 | + | 시드 블록 암호 알고리즘은 민간 부분인 인터넷, 전자상거래, 무선 통신 등에서 공개 시 민감한 영향을 미칠 수 있는 정보의 보호와 개인 프라이버시 등을 보호하기 위하여 1992년 2월 한국 정보보호센터(KISA)에 의해 개발된 [[대칭키 암호 알고리즘]]이다. 대칭키 블록 암호 알고리즘으로 비밀성을 제공하는 [[암호]]시스템의 중요 요소이다. 블록 암호 알고리즘 SEED는 128비트의 비밀키를 이용해 128비트의 [[평문]]을 [[암호문]]으로 변환한다. 금융권, 전자상거래, 정보 보호 제품(VPN) 등의 다양한 분야에서 데이터의 기밀성과 무결성 기능을 제공하기 위해 사용되고 있다. 국외 주요 정보 보호 업체를 포함한 670개 이상의 국내 외 산업계와 학계와 연구 분야에서 SEED를 사용하고 있다. 블록 암호 알고리즘의 경우, 암호 알고리즘이 적용되는 블록 크기가 정해져 있기 때문에 정해진 길이보다 긴 데이터를 암호화하거나 데이터 무결성 검증을 하기 위해서는 블록 암호 알고리즘의 운영 모드를 반드시 사용하게 된다. 입력 데이터의 길이가 기본 블록 크기의 배수가 되지 않으면 처리가 불가능하므로 입력 메시지의 길이가 기본 블록 크기의 배수가 되지 않으면 처리가 불가능해 입력 메시지의 길이가 블록 길이의 배수가 되도록 하기 위해 덧붙이기 방법을 사용해야 한다. 이에, 한국 정보보호진흥원에서는 안전성 측면과 효율성 측면을 고려하여 SEED의 사용을 촉진하기 위해 SEED의 운영 모드를 [[TTA]] 표준으로 제안하여 2003년 12월 TTA 표준으로 제정하였다. 128비트 블록 암호 SEED를 국민이 쉽게 활용할 수 있도록 ECB, CBC, CTR, CCM, GCM, CMAC 운영 모드에 대한 소스 코드를 배포하고 있다. 배포하는 소스 코드의 언어는 [[C 언어]], [[C++]], [[자바]], [[ASP]], [[JSP]], [[PHP]]로 구성된다. |
− | *1999년 9월 | + | |
+ | == 역사 == | ||
+ | *1999년 2월 한국 인터넷진흥원과 국내 암호전문가들이 개발 | ||
+ | *1999년 9월 정보통신 단체표준(TTA)으로 제정 | ||
*2005년 국제 표준화 기구인 ISO/IEO 국제 블록 암호 알고리즘, IETF 표준으로 제정 | *2005년 국제 표준화 기구인 ISO/IEO 국제 블록 암호 알고리즘, IETF 표준으로 제정 | ||
*2009년 256비트 키를 지원하는 SEED 256 개발 | *2009년 256비트 키를 지원하는 SEED 256 개발 | ||
− | == | + | == 구조 == |
− | *[[ | + | [[파일:SEED_전체_구조도.png|300픽셀|오른쪽|'''SEED 전체 구조도''']] |
− | *[[ | + | SEED 알고리즘은 전체적으로 파이스텔(Feistel) 구조로 이루어져 있다. 128비트의 평문 블록과 128비트 키를 입력으로 사용해서 총 16라운드에 걸쳐 128비트 암호문 블록을 출력한다. |
− | *[[ARIA]] | + | |
− | [[ | + | === F함수 === |
+ | 파이스텔 구조 형태인 블록 암호 알고리즘은 F 함수의 특성에 따라서 구분될 수 있다. SEED의 F 함수는 수정된 64피트 파이스텔 형태로 구성되는데, 각 32비트 블록 2개를 입력받아서 32비트 블록 2개를 출력한다. 즉, 전자의 경우를 C와 D라고 하고 후발대는 C'와 D'라고 할 때, 암호화 과정에서 64비트 블록인 C, D와 64비트 라운드 키 <math>K_{i}=(K_{i, 0};K_{i, 1})</math>를 F 함수의 입력으로 처리해서 64비트 블록인 C'와 D'를 출력한다. 참고로 여기서 i란 라운드 수를 의미한다. | ||
+ | |||
+ | <math> C' = G[G[G \left\{(C \oplus K_{i, 0}) \oplus (D \oplus K_{i, 1})\right\} \boxplus (C \oplus K_{i, 0})] \boxplus G \left\{(C \oplus K_{i, 0}) \oplus (D \oplus K_{i, 1}) \right\}] </math> | ||
+ | <math> \qquad \quad \boxplus G[G{(C \oplus K_{i, 0}) \oplus (D \oplus K_{i, 1})} \boxplus (C \oplus K_{i, 0})]</math> | ||
+ | <math> D' = G[G[G[\left\{(C \oplus K_{i, 0})\oplus(D \oplus K_{i, 1})\right\} \boxplus (C \oplus K_{i, 0})] \boxplus G \left\{(C \oplus K_{i, 0}) \oplus (D \oplus K_{i, 1})\right\}]</math> | ||
+ | |||
+ | === G 함수 === | ||
+ | 전체 G 함수는 다음과 같이 기술된다. | ||
+ | <math>Y_3 = S_2(X_3), \quad Y_2=S_1(X_2) \quad Y_1=S_2(X_1), \quad Y_0=S_1(X_0),</math> | ||
+ | <math>\qquad Z_3=(Y_0 \And m_3) \oplus (Y_1 \And m_0) \oplus (Y_2 \And m_1) \oplus (Y_3 \And m_2)</math> | ||
+ | <math>\qquad Z_2=(Y_0 \And m_2) \oplus (Y_1 \And m_3) \oplus (Y_2 \And m_0) \oplus (Y_3 \And m_1)</math> | ||
+ | <math>\qquad Z_1=(Y_0 \And m_1) \oplus (Y_1 \And m_2) \oplus (Y_2 \And m_3) \oplus (Y_3 \And m_0)</math> | ||
+ | <math>\qquad Z_0=(Y_0 \And m_0) \oplus (Y_1 \And m_1) \oplus (Y_2 \And m_2) \oplus (Y_3 \And m_3)</math> | ||
+ | <math>\quad (m_0=0xfc, \quad m_1=0xf3, \quad m_2=0xcf, \quad m_3=0x3f )</math> | ||
+ | 참고로 위의 G 함수는 구현의 효율성을 위하여 4개의 확장된 4바이트 SS-box들의 배타적 논리합으로 구현할 수 있다. 그러기 위해선 다음과 같이 4개의 SS-box들을 저장해야 한다. | ||
+ | <math> SS_3=S_2(X_3) \And m_2 || S_2(X_3) \And m_1 || S_2(X_3) \And m_0 || S_2(X_3) \And m_3, </math> | ||
+ | <math> SS_2=S_1(X_2) \And m_1 || S_1(X_2) \And m_0 || S_1(X_2) \And m_3 || S_1(X_2) \And m_2, </math> | ||
+ | <math> SS_1=S_2(X_1) \And m_0 || S_2(X_1) \And m_3 || S_2(X_1) \And m_2 || S_2(X_1) \And m_1, </math> | ||
+ | <math> SS_0=S_1(X_2) \And m_3 || S_1(X_2) \And m_2 || S_1(X_2) \And m_1 || S_1(X_2) \And m_0, </math> | ||
+ | 이 확장 SS-box들을 이용하면 G 함수는 다음처럼 구현할 수 있다. | ||
+ | <math> Z=SS_3(X_3) \oplus SS_2(X_2) \oplus SS_1(X_1) \oplus SS_0(X_0) </math> | ||
+ | |||
+ | === S-Box === | ||
+ | G 함수의 내부에 사용되는 비선형 S-box <math> S_1, S_2 </math>을 생성하기 위해 다음 식이 사용되었다. <math> (n_1=247, n_2=251, b_1=169, b_2=56) </math> | ||
+ | <math> S_i : Z_{2^8} \rightarrow Z_{2^8} , S(x)=A^{(i)} \cdot x^{n_i} \oplus b_i </math> | ||
+ | |||
+ | <math> A^{(1)} = \begin{pmatrix} 1&0&0&0&1&0&1&0 \\ 1&1&1&1&1&1&1&0 \\ 1&0&0&0&0&1&0&1 \\ 0&1&0&0&0&0&1&0 \\ 0&1&0&0&0&1&0&1 \\ 0&0&1&0&0&0&0&1 \\ 1&0&0&0&1&0&0&0 \\ 0&0&0&1&0&1&0&0 \end{pmatrix}, A^{(2)} = \begin{pmatrix} 0&1&0&0&0&1&0&1 \\ 1&0&0&0&0&1&0&1 \\ 1&1&1&1&1&1&1&0 \\ 0&0&1&0&0&0&0&1 \\ 1&0&0&0&1&0&1&0 \\ 1&0&0&0&1&0&0&0 \\ 0&1&0&0&0&0&1&0 \\ 0&0&0&1&0&1&0&0 \end{pmatrix} </math> | ||
+ | |||
+ | === 라운드 키 생성과정 === | ||
+ | SEED의 라운드 키를 생성하는 과정은 우선 128비트 암호키를 64비트씩 좌우로 나누어서 이들을 8비트씩 교대로 좌우로 회전이동한다. 그 후, 결과의 4워드들에 대해 간단한 산술 연산과 G 함수를 적용해서 라운드 키를 생성한다. 라운드 키 생성 과정은 기본적으로 하드웨어나 제한된 자원을 가지는 스마트카드 같은 곳에서 효율적으로 응용할 수 있도록 만들기 위해, 암호화나 복호화를 진행할 때 암호키에서 필요한 라운드 키를 간단하게 계산할 수 있도록 설계되었다. | ||
+ | |||
+ | 주어진 128비트 암호키가 K=A||B||C||D일 때, 해당 암호키를 32비트 레지스터인 A, B, C, D로 나눈다. 각 라운드 i 에 사용되는 키 K_i=(K_{i,0}:K_{i,1})는 다음과 같은 방식으로 생성한다.<ref>한국인터넷진흥원, 〈[SEED 128 알고리즘 상세 명세서]〉, 《한국인터넷진흥원》, 2009-07</ref> | ||
+ | |||
+ | <math> for(i=1; i<=16; i++)</math>{ | ||
+ | <math> \qquad K_{i,0} \leftarrow G(A+C-KC_{i-1}); </math> | ||
+ | <math> \qquad K_{i,1} \leftarrow G(B-D+KC_{i-1}); </math> | ||
+ | <math> \qquad if(i%2==1) A||B \leftarrow (A||B)^{>>8}; </math> | ||
+ | <math> \qquad else \quad C||D \leftarrow (C||D)^{>>8}; </math> | ||
+ | } | ||
+ | :{|class=wikitable width=600 style="background-color:#ffffee" text-align: center | ||
+ | |+<big>'''라운드키 생성과정에 사용된 상수'''</big> | ||
+ | !align=center style="background-color:#ffeecc" colspan=2|라운드 상수 | ||
+ | |- | ||
+ | |align=center|<math> \mathrm{KC_0} </math> = 0x9e3779b9 | ||
+ | |align=center|<math> \mathrm{KC_8} </math> = 0x3779b99e | ||
+ | |- | ||
+ | |align=center|<math> \mathrm{KC_1} </math> = 0x3c6ef373 | ||
+ | |align=center|<math> \mathrm{KC_9} </math> = 0x6ef3733c | ||
+ | |- | ||
+ | |align=center|<math> \mathrm{KC_2} </math> = 0x78dde6e6 | ||
+ | |align=center|<math> \mathrm{KC_{10}} </math> = 0xdde6e678 | ||
+ | |- | ||
+ | |align=center|<math> \mathrm{KC_3} </math> = 0xf1bbcdcc | ||
+ | |align=center|<math> \mathrm{KC_{11}} </math> = 0xbbcdccf1 | ||
+ | |- | ||
+ | |align=center|<math> \mathrm{KC_4} </math> = 0xe3779b99 | ||
+ | |align=center|<math> \mathrm{KC_{12}} </math> = 0x779b99e3 | ||
+ | |- | ||
+ | |align=center|<math> \mathrm{KC_5} </math> = 0xc6ef3733 | ||
+ | |align=center|<math> \mathrm{KC_{13}} </math> = 0xef3733c6 | ||
+ | |- | ||
+ | |align=center|<math> \mathrm{KC_6} </math> = 0x8dde6e67 | ||
+ | |align=center|<math> \mathrm{KC_{14}} </math> = 0xde6e678d | ||
+ | |- | ||
+ | |align=center|<math> \mathrm{KC_7} </math> = 0x1bbcdccf | ||
+ | |align=center|<math> \mathrm{KC_{15}} </math> = 0xbcdccf1b | ||
+ | |} | ||
+ | |||
+ | == 특징 == | ||
+ | === 표준화 현황 === | ||
+ | SEED는 1999년 9월 정보통신단체 표준으로 제정되었고, 2005년에는 국제 표준화 기구인 ISO/IEC 국제 블록 암호 알고리즘 IETF 표준으로 제정되었다. 국내외의 표준명은 각각 다음과 같다. | ||
+ | * '''국내''' : TTAS.KO-12.0004/R1 : 128비트 블록 암호 알고리즘(SEED) | ||
+ | * '''국외''' : ISO/IEC 18033-3 : 정보기술보안기술(Information technology Security techniques), 암호화(Encryption), Part 3 : Block ciphers, IETF RFC 4269 : SEED 암호화 알고리즘(The SEED Encryption Algorithm) 4가지가 있으며, RFC4269은 RFC 4009 (The SEED Encryption Algorithm)의 개정 표준이다. | ||
+ | SEED 암호 알고리즘 자체에 대한 표준 외에도 SEED를 사용하기 위한 다양한 국내외 표준들도 제정되었다. 이에 해당하는 국내외 표준명은 다음과 같다. | ||
+ | * '''국내''' : TTAS.KO-12.0025 : 블록 암호 알고리즘 SEED의 운영 모드 | ||
+ | * '''국외''' : IETF RFC 4010 : 보안 전자우편에서의 메시지 암호화를 위한 SEED 사용표준, IETF RFC 4162 : TLS를 위한 SEED 알고리즘 사용표준, IETF RFC 4196 : IPsec을 위한 SEED 알고리즘 사용표준<ref name='표준화 및 보급신청'>한국인터넷진흥원 공식홈페이지 SEED - https://seed.kisa.or.kr/kisa/algorithm/EgovSeedInfo.do</ref> | ||
+ | |||
+ | === 보급 신청 === | ||
+ | * '''지식재산권''' : 한국인터넷진흥원은 SEED를 이용한 제품의 생산이나 판매와 관련된 지식재산권에 대하여 별도의 사용료를 요구하지 않는다. | ||
+ | * '''소스 코드''': SEED는 [[전자상거래]], [[이메일]], [[인터넷뱅킹]], 데이터 저장, VPN, 지식재산권 보호 등의 다양한 분야에서 사용될 수 있고, 사용되고 있다. 한국인터넷진흥원은 2009년 5월 말 기준, nCipher, RSA Security 등의 국외 정보보호 업체들을 포함하여 총 3,232개 이상의 국내외 기업 및 학교에 SEED 소스 코드를 이메일을 이용하여 전달했다. 현재 배포하고 있는 SEED 소스 코드는 32비트 프로세서에 맞도록 C언어와 자바 언어로 구현되었다.<ref name='표준화 및 보급신청'></ref> | ||
+ | |||
+ | === 블록 암호 알고리즘 === | ||
+ | 암호는 허락받지 않은 제삼자가 메시지를 해독할 수 없도록 상태를 변환하거나 암호화된 메시지를 해독할 수 있도록 변환하는 기술이다. 이 과정에서 해독 가능한 형태로 바꾸는 과정 복호화라고 부르며, 반대로 해독할 수 없는 상태로 바꾸는 과정은 암호화라고 칭한다. 또한, 해독할 수 있는 형태의 메시지는 평문이라고 부르며, 해독할 수 없는 상태의 메시지는 암호문이라고 한다. 정보를 숨기고 숨긴 정보를 읽고 해석하기 위해선 권한이 있는 사람만이 암호화와 복호화를 진행할 수 있어야 하므로, 이러한 비밀 정보는 비밀키라고 불리며, 암호화에 필요한 암호화 키와 복호화에 필요한 복호화키로 분류한다. 암호는 키의 특성에 따라 암호화 키와 복호화키가 같은 암호를 대칭키암호 또는 비밀키 암호라고 하는데, 암호화 키와 복호화키가 다른 암호는 비대칭 키 암호 또는 공개키 암호라고 부른다. 또한, 대칭키 암호는 다시 암호화 및 복호화 처리를 하는 방법에 따라, 메시지를 블록 단위로 나누어서 처리하는 블록 암호와 메시지를 비트 단위로 처리하는 스트림 암호로 분류한다. SEED는 128비트의 암호화 복호화 키를 사용해서 임의의 길이를 갖는 입력 메시지를 128비트의 블록 단위로 처리하는 128비트 블록 암호 알고리즘에 해당하며, 따라서 임의의 길이를 가지는 평문 메시지를 128비트씩 블록 단위로 나누고 암호화하고 암호문을 생성하여 소프트웨어 및 하드웨어의 보안에 기여한다.<ref name='시드 매뉴얼'>관리자1, 〈[https://seed.kisa.or.kr/kisa/Board/17/detailView.do 암호알고리즘 소스코드]〉, 《한국인터넷진흥원》, 2019-01-31</ref> | ||
+ | |||
+ | == 고려사항 == | ||
+ | SEED를 실제로 사용하기 위해서는 구현 환경에서 사용되는 [[엔디안]](Endianness)과 암호화된 데이터가 저장되는 데이터 형식을 고려해야 한다. 또한, 입력 블록을 블록 암호에 적용하는 방법인 운영 모드와 마지막 블록의 크기를 맞추기 위한 [[패딩]]을 함께 구현해 주어야 한다. | ||
+ | |||
+ | === 엔디안 === | ||
+ | 컴퓨터 메모리의 바이트를 배열하는 순서를 [[엔디안]]이라고 부른다. 엔디안은 보통 큰 단위가 앞에 나오는 빅 에디안, 작은 단위가 앞에 나오는 리틀 엔디안, 두 경우에 속하지 않거나 둘 모두를 지원하는 미들 엔디안으로 분류된다. 현재 [[빅 엔디안]]과 [[리틀 엔디안]]이 많이 사용되지만, 일반적인 데스크탑에서는 [[x86]] 아키텍처를 많이 사용하고 있고 x86 아키텍처는 리틀 엔디안 구조를 사용하기 때문에, 한국인터넷진흥원에서는 기본적으로 리틀 엔디안을 적용한 SEED 소스 코드를 배포하고 있다. 엔디안은 암호 알고리즘을 구현할 때 중요하게 고려해야 할 문제 중 하나인데, 대부분의 암호 알고리즘은 비트 단위로 연산을 처리하기 때문에 바이트 배열이 서로 맞지 않으면 같은 알고리즘으로 같은 메시지를 암호화하더라도 서로 다른 암호문을 생성할 수 있다. 자바 가상머신은 기본적으로 빅 엔디안은 사용하기 때문에 자바 소스 코드에서는 엔디안에 기본적으로 빅 엔디안이 설정되어 있는데, 상황에 따라 사용자는 시스템의 엔디안에 맞게 수동으로 선택해 주어야만 한다. | ||
+ | |||
+ | === 데이터 형식 === | ||
+ | 일반적으로 암호 알고리즘은 비트 단위의 연산을 포함한 다양한 연산을 수행해서 평문 메시지를 무의미한 비트열인 암호문으로 변환한다. 여기서 만들어진 암호문 비트열은 반복이 없는 무작위에 의한 비트들로 구성되기 때문에 이를 문자열 형태로 저장하거나 처리할 때는 문제가 발생할 수 있다. 따라서 암호화된 메시지는 항상 문자열이 아니라 이진 형태로 처리해야 한다. 다음과 같이 C 언어 코드로 만든 예시가 있다고 하자. ch 배열에 저장되는 값은 0x41, 0x42, 0x00, 0x44, 0x45지만, 만약 이를 문자열로 출력한다면 ch[3] = 0x00 = NULL 값으로 인해 0x41, 0x42에 해당하는 'AB'만 출력된다. 따라서 암호화된 메시지는 항상 문자열이 아니라 HEX 형태로 처리해야 한다. | ||
+ | char ch[ ] = {0x41, 0x42, 0x00, 0x44, 0x45}; | ||
+ | printf("%s", ch); | ||
+ | |||
+ | === 운영 모드 === | ||
+ | 운영 모드는 여러 개의 입력 블록들을 블록 암호에 적용해서 암호화 및 복호화하는 방법에 대한 정의를 말한다. 이러한 운영 모드는 블록 암호와는 독립적으로 정의되는데, 대표적으로 가장 널리 이용되는 블록 암호의 기밀성 운영 모드에는 ECB 모드, CBC 모드, CFB 모드, OFB 모드, CTR 모드가 있고, 인증 운영 모드에는 CMAC 모드, 인증 암호화 운영 모드에는 CCM 모드, GCM 모드가 있다. 다음은 이 중 ECB, CBC, CTR, CCM, GCM, CMAC 모드에 대한 설명이다. | ||
+ | |||
+ | * '''ECB 운영 모드''' | ||
+ | :ECD 모드는 평문 블록을 암호문 블록으로 독립적으로 암호화하는 운영 모드이다. 암호화 과정은 평문 블록을 입력 블록으로 설정하고, 이를 암호화한 출력 블록을 암호문 블록으로 설정한다. 복호화 과정은 평문 블록을 입력 블록으로 설정하고, 이를 암호화한 출력 블록을 암호문 블록으로 설정한다. | ||
+ | |||
+ | * '''CBC 운영 모드''' | ||
+ | :CBC 모드는 동일한 평문 블록과 암호문 블록 쌍이 발생하지 않도록 전 단계의 암호화 및 복호화 결과가 현 단계에 영향을 주는 운영 모드이다. CBC 모드의 암호화 과정은 현 단계에서 평문 블록과 전 단계의 암호문 블록을 배타적 논리합 연산한 결과를 현 단계의 입력 블록으로 설정하고, 이를 암호화한 출력 블록을 현 단계의 암호문 블록으로 설정한다. 복호화 과정은 현 단계의 암호문 블록을 입력 블록으로 설정한 후, 이를 복호화한 출력 블록을 전 단계의 입력 블록인 암호문 블록과 배타적 논리합 연산한 결과를 현 단계의 평문 블록으로 한다. | ||
+ | |||
+ | * '''CTR 운영 모드''' | ||
+ | :CTR 모드는 각 단계에 따라 증가하는 카운트 블록을 입력 블록으로 사용하는 운영 모드이다. 암호화 과정은 카운터를 현 단계의 입력 블록으로 해서 암호화한 출력 블록을 평문 블록과 배타적 논리합 연산을 수행해서 암호문 블록을 생성한다. 복호화 과정은 카운터를 현 단계의 입력 블록으로 하고, 암호화한 출력 블록을 암호문 블록과 배타적 논리합 연산을 수행해서 평문 블록을 생성한다. | ||
+ | |||
+ | * '''CCM 운영 모드''' | ||
+ | :CCM 운영 모드는 CTR 모드에 CBC-MAC의 메시지 인증을 포함한 128비트 전용 운영 모드이다. CCM 모드의 암호화 과정은 입력 데이터로부터 데이터 블록 열과 초기 카운터 블록을 생성하는 것부터 시작한다. 데이터 블록 열은 CBC-MAC의 출력값을 얻는 데 사용되고, 인증값은 초기 카운터 블록에 의한 암호화 함수의 출력 블록과 CBC-MAC 출력값의 XOR 결과를 최상위 비트부터 주어진 인증값 길이만큼 절삭한 값으로 설정한다. 그리고 CTR 모드를 통해 평문에 대한 암호문을 생성한다. 최종 출력은 CTR 모드에서 얻어진 암호문과 CBC-MAC에서 얻어진 인증값을 연접한 결과이다. CCM 모드의 복호화 과정은 입력 데이터에서 초기 카운터 블록을 생성하는 것부터 시작한다. 초기 카운터 블록에 대한 암호화 함수 출력 블록은 입력 데이터에 포함된 인증값과 XOR 하는데, 그 결과는 마지막 단계에서 CBC-MAC의 출력값과 비교하는 데 사용된다. 이어서 암호문에 대한 평문은 CTR 모드를 통해 생성된다. 데이터 블록 열을 생성한 후에, 이에 대한 CBC-MAC의 출력값을 최상위 비트부터 주어진 인증값 길이만큼 절삭하여 인증값으로 설정한다. 마지막으로 복호화 과정에서 계산된 인증값과 입력 데이터에 포함된 인증값을 비교하여, 일치한다면 평문을 출력하고 그렇지 않다면 오류 플래그를 출력한다. | ||
+ | |||
+ | * '''GCM 운영 모드''' | ||
+ | :GCM 모드는 CTR 모드에 유한체 상의 곱 연산을 이용한 메시지 인증을 포함한 128비트 전용 운영 모드이다. GCM의 암호화 과정은 먼저 인증값 계산에 사용할 보조 비밀키와 초기 카운터 블록을 생성하는 것부터 시작한다. 그리고 하위의 32비트에 대해서 1 증가시킨 카운터 블록을 초깃값으로 해서 CTR 모드를 통해 평문에 대한 암호문을 생성한다. 암호문과 부가 인증 데이터는 정해진 함수의 출력값을 얻는 데 사용되며, 인증값은 초기 카운터에 대한 암호화 함수의 출력 블록과 정해진 함수 출력의 XOR 결과를 최상위 비트부터 주어진 인증값 길이만큼 절삭한 값으로 설정한다. 최종 출력은 CTR 모드로부터 얻어진 암호문과 정해진 함수에서 얻어진 인증값을 연접한 결과이다. GCM의 복호화 과정은 먼저 인증값 계산에 사용할 보조 비밀키와 초기 카운터 블록을 생성하는 것부터 시작한다. 그리고 하위의 32비트에 대해 1 증가시킨 카운터 블록을 초깃값으로 한 CTR 모드를 통해서 암호문에 대한 평문을 생성한다. 이어서 인증값은 초기 카운터에 대한 암호화 함수의 출력 블록과 정해진 함수 출력의 XOR 결과를 최상위 비트부터 주어진 인증값 길이만큼 절삭한 값으로 설정한다. 마지막으로 복호화 과정에서 계산된 인증값과 입력 데이터에 포함된 인증값을 비교해서, 일치한다면 평문을 출력하고 그렇지 않다면 오류 플래그를 출력한다. | ||
+ | |||
+ | * '''CMAC 운영 모드''' | ||
+ | :CMAC는 CBC 모드에서 파생된 메시지 인증 방식 CBC-MAC을 안전성 측면에서 개선한 운영 모드이다. CMAC의 인증값 생성 과정은 먼저 메시지를 b 비트 단위로 분할하고, 분할된 각 블록을 차례대로 <math>M_1, M_2, ..., M_{m-1}, M_m^*</math>로 표시한다. 여기서 블록 <math>M_m^*</math>의 길이는 b 비트 이하이다. 그리고 (m-1)개의 메이지 블록 열 <math>M_1, M_2, ..., M_{m-1}</math>에서 현재 단계의 메시지 블록과 직전 단계 블록 암호 암호화 함수 출력 블록의 XOR 결과를 암호화 함수의 입력 블록으로 설정해서 현재 단계 출력 블록을 얻는 구성을 반복한다. 마지막 메시지 블록(M_m^*)을 처리할 때 해당 메시지 블록의 길이가 b비트인가 여부에 따라서 비밀키 K로부터 생성한 보조 비밀키와 직전 단계 암호화 함수 출력 블록, 그리고 메시지 블록(M_m^*)의 XOR 결과를 블록 암호 암호화 함수 입력 블록으로 설정한다. 이렇게 얻은 블록 암호 암호화 함수 출력 블록의 상위 비트를 인증값으로 설정한다. 수신한 메시지 M과 인증값 T가 유효한지를 검증하기 위해서 비밀키 K를 사용해서 직접 인증값 <math>T_1</math>을 계산한 후, <math>T_1=T</math> 여부를 확인한다. | ||
+ | |||
+ | === 패딩 === | ||
+ | 메시지를 HIGHT에 입력하기 위해 여러 개의 64비트 블록으로 나눌 때, 마지막 블록을 정확히 64비트 블록으로 크기를 맞추는 일은 현실적으로 쉽지 않고 어려운 일이다. 예를 들어 300비트짜리 메시지를 64비트의 블록으로 나눈다고 할 때, 130=64+64+2로 나누어서 세 개의 블록을 구성하게 되는데, 이때 마지막 블록이 2비트로 64비트를 만족하지 못한다. 이 경우에 나머지 부족한 62비트를 채워주어야만 HIGHT의 입력값으로 사용이 가능하다. 이렇게 부족한 부분을 채우는 방식을 바로 패딩이라고 일컫는다. ECB, CBC 모드는 평문 블록을 암호화의 입력으로 사용하고, 평문 데이터의 크기가 64비트의 양의 정수배가 되어야 하므로 반드시 덧붙이기 방법이 적용해야 한다. 그러나 CFB-s, OFB, CTR 모드의 경우에는 마지막 암호화 단계의 평문 블록이 64비트를 만족하지 못하고, CFB-s 모드의 경우에는 s를 만족하지 못하고 m비트가 남아있을 때, 마지막 출력 블록인 64비트 중 상위의 m비트와 마지막 평문 블록 m비트와 배타적 논리합 연산 합으로 다음과 같은 덧붙이기 방법을 적용하지 않을 수도 있다. 다음에 설명할 패딩 방법들은 ISO/IEC 국제표준 및 PKCS에서 사용하는 방법이기도 하며, 적용되는 시스템에 맞도록 사용함을 권고하고 있다. 그러나 패딩 방법 1의 경우에는 복호화된 평문 데이터의 크기가 명확하지 않은 경우가 일어나기 때문에 평문 데이터의 크기가 명확히 알려진 경우에만 사용할 것을 권고하고 있다. | ||
+ | |||
+ | * '''패딩 방법 1''' | ||
+ | :평문 데이터의 크기가 64비트 양의 정수배가 아닐 경우, 마지막 평분 블록이 64비트가 되도록 바이트 '00'을 덧붙인다. | ||
+ | 입력 블록( 48비트) : 4F 52 49 54 48 4D | ||
+ | 패딩 블록(128비트) : 4F 52 49 54 48 4D 00 00 00 00 00 00 00 00 00 00 | ||
+ | 입력 블록(128비트) : 53 45 45 44 41 4C 47 A8 3E D1 80 F1 29 DC 4A 78 | ||
+ | 패딩 블록(128비트) : 53 45 45 44 41 4C 47 A8 3E D1 80 F1 29 DC 4A 78 | ||
+ | |||
+ | * '''패딩 방법 2''' | ||
+ | :평문 데이터의 크기가 64비트의 양의 정수배가 아닌 경우, 마지막 평문 블록이 64비트가 되도록 평문 데이터의 끝에 비트 '80'을 추가하고, 나머지는 모두 '0'비트를 덧붙인다. 그리고 평문 블록의 크기가 64비트의 양의 정수배일 경우에는 추가적인 128비트 '80...00' 블록을 추가한다. | ||
+ | 입력 블록( 48비트) : 4F 52 49 54 48 4D | ||
+ | 패딩 블록(128비트) : 4F 52 49 54 48 4D 80 00 00 00 00 00 00 00 00 00 | ||
+ | 입력 블록(128비트) : 53 45 45 44 41 4C 47 A8 3E D1 80 F1 29 DC 4A 78 | ||
+ | 패딩 블록(256비트) : 53 45 45 44 41 4C 47 A8 3E D1 80 F1 29 DC 4A 78 | ||
+ | 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ||
+ | |||
+ | * '''패딩 방법 3''' | ||
+ | :평문 데이터의 크기가 128비트 양의 정수배가 아닌 경우에는, 마지막 평문 블록이 128비트가 되도록 덧붙이기가 필요한 바이트 수 'xx...xx'를 덧붙인다. 그리고 평문 블록의 크기가 128비트의 양의 정수배인 경우에는 추가적인 128비트 '0F...0F' 블록을 추가한다. | ||
+ | 입력 블록( 48비트) : 4F 52 49 54 48 4D | ||
+ | 패딩 블록(128비트) : 4F 52 49 54 48 4D 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A | ||
+ | 입력 블록(128비트) : 53 45 45 44 41 4C 47 A8 3E D1 AF 07 4A 73 12 2C | ||
+ | 패딩 블록(256비트) : 53 45 45 44 41 4C 47 A8 3E D1 AF 07 4A 73 12 2C | ||
+ | 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F | ||
+ | |||
+ | === 활용 방법 === | ||
+ | 메시지를 HIGHT에 입력하기 위해서 여러 개의 64비트 블록으로 나눌 때, 마지막 블록을 정확히 64비트의 블록 크기로 맞추기는 어렵다. 예를 들어, 300비트의 메시지를 64비트의 블록으로 나눈다고 하면 130=64+64+2로 나누어서 세 개의 블록을 구성하게 된다. SEED 알고리즘은 16바이트의 비밀키, 16바이트의 평문을 입력으로 16바이트의 암호문을 출력하는 블록 암호 알고리즘이다. 한국인터넷진흥원에서 제공하는 소스 코드에는 두 가지 방법의 함수가 포함되어 있다. 첫 번째 방법은 처리하고자 하는 데이터가 적을 경우에 쓰이는 방법으로, Encrypt와 Decrypt 함수만 호출하면 암호화와 복호화가 된다. 두 번째 방법은 대용량의 데이터를 암호화 및 복호화할 때 3가지 단계로 데이터 크기가 버퍼보다 클 경우 사용되는 방법이다.<ref name='시드 매뉴얼'></ref> | ||
+ | |||
+ | == 소스 코드 == | ||
+ | === C/C++ === | ||
+ | * '''SEED-ECB''' | ||
+ | # void SEED_KeySched( DWORD *pdwRoundKey, BYTE *UserKey ); | ||
+ | # void SEED_Encrypt( BYTE *pbData, DWORD *pdwRoundKey ); | ||
+ | # void SEED_Decrypt( BYTE *pbData, DWORD *pdwRoundKey ); | ||
+ | |||
+ | * '''SEED-CBC''' | ||
+ | # int SEED_CBC_Encrypt( IN BYTE *pbszUserKey, IN BYTE *pbszIV, IN BYTE *pbszPlainText, IN int nPlainTextLen, OUT BYTE *pbszCipherText ) | ||
+ | # int SEED_CBC_Decrypt( IN BYTE *pbszUserKey, IN BYTE *pbszIV, IN BYTE *pbszCipherText, IN int nCipherTextLen, OUT BYTE *pbszPlainText ) | ||
+ | # int SEED_CBC_init( OUT KISA_SEED_INFO *pInfo, IN KISA_ENC_DEC enc, IN BYTE *pbszUserKey, IN BYTE *pbszIV ) | ||
+ | # int SEED_CBC_Process( OUT KISA_SEED_INFO *pInfo, IN DWORD *in, IN int inLen, OUT DWORD *out, OUT int *outLen ) | ||
+ | # int SEED_CBC_Close( OUT KISA_SEED_INFO *pInfo, IN DWORD *out, IN int *outLen ) | ||
+ | |||
+ | * '''SEED-CTR''' | ||
+ | # int SEED_CTR_Encrypt( IN BYTE *pbszUserKey, IN BYTE *pbszIV, IN BYTE *pbszPlainText, IN | ||
+ | # int nPlainTextLen, OUT BYTE *pbszCipherText ) | ||
+ | # int SEED_CTR_Decrypt( IN BYTE *pbszUserKey, IN BYTE *pbszIV, IN BYTE *pbszCipherText, IN int nCipherTextLen, OUT BYTE *pbszPlainText ) | ||
+ | # int SEED_CTR_init( OUT KISA_SEED_INFO *pInfo, IN KISA_ENC_DEC enc, IN BYTE *pszUserKey, IN BYTE *pbszCounter ) | ||
+ | # int SEED_CTR_Process( OUT KISA_SEED_INFO *pInfo, IN DWORD *in, IN int inLen, OUT DWORD *out, OUT int *outLen ) | ||
+ | # int SEED_CTR_Close( OUT KISA_SEED_INFO *pInfo, IN DWORD *out, IN int *outLen ) | ||
+ | |||
+ | * '''SEED-CCM''' | ||
+ | # int SEED_CCM_Encryption(unsigned char *ct, unsigned int *ctLen, unsigned char *pt, unsigned int ptLen, unsigned int macLen, unsigned char *nonce, unsigned int nonceLen, unsigned char *aad, unsigned int aadLen, unsigned char *mKey) | ||
+ | # int SEED_CCM_Decryption(unsigned char *pt, unsigned int *ptLen, unsigned char *ct, unsigned int ctLen, unsigned int macLen, unsigned char *nonce, unsigned int nonceLen, unsigned char *aad, unsigned int aadLen, unsigned char *mKey) | ||
+ | |||
+ | * '''SEED-GCM''' | ||
+ | # int SEED_GCM_Encryption(unsigned char *ct, unsigned int *ctLen, unsigned char *pt, unsigned int ptLen, unsigned int macLen, unsigned char *nonce, unsig | ||
+ | # int SEED_GCM_Decryption(unsigned char *pt, unsigned int *ptLen, unsigned char *ct, unsigned int ctLen, unsigned int macLen, unsigned char *nonce, unsigned int nonceLen, unsigned char *aad, unsigned int aadLen, unsigned char *mKey) | ||
+ | |||
+ | * '''SEED-CMAC''' | ||
+ | # int SEED_Generate_CMAC(unsigned char *pMAC, int macLen, unsigned char *pIn, int inLen, unsigned char *mKey) | ||
+ | # int SEED_Verify_CMAC(unsigned char *pMAC, int macLen, unsigned char *pIn, int inLen, unsigned char *mKey) | ||
+ | |||
+ | === 자바 === | ||
+ | * '''SEED-ECB''' | ||
+ | # public static byte[] SEED_ECB_Encrypt( byte[] pbszUserKey, byte[] pbData, int offset, int length ); : SEED-ECB 알고리즘 암호화 함수이다. pbszUserKey는 사용자가 지정하는 16바이트 입력 키고, pbData는 사용자 입력 평문이다. offset은 사용자 입력 길이 시작 오프셋을, length는 사용자 입력 길이를 의미하는 매개변수이다. 사용자 입력에 대한 암호문 출력 바이트를 반환한다. 고려해야 할 점은 pbszUserKey의 크기는 반드시 16바이트여야만 한다. | ||
+ | # public static byte[] SEED_ECB_Decrypt( byte[] pbszUserKey, byte[] pbData, int offset, int length ); : SEED-ECB 알고리즘 복호화 함수이다. 매개변수 pbszUserKey는 사용자가 지정하는 16바이트 입력 키고, pbData는 사용자 입력 암호문이다. offset은 사용자 입력 길이 시작 오프셋이며, length는 사용자 입력 길이를 의미하는 매개변수이다. 사용자 입력에 대한 평문 출력 바이트를 반환하는 함수로, 위와 마찬가지로 pbszUserKey의 크기는 반드시 16바이트이어야 한다. | ||
+ | |||
+ | * '''SEED-CBC''' | ||
+ | # public static byte[] SEED_CBC_Encrypt( byte[] pbszUserKey, byte[] pbszIV, byte[] message, int message_offset, int message_length ) : SEED-CBC 알고리즘 암호화 함수이다. 매개변수 pbszUserKey는 사용자가 지정하는 16바이트 입력 키이고, pbszIV는 사용자가 지정하는 16바이트 초기화 벡터이다. message는 사용자 입력 평문을 가리키며, message_offset은 사용자 입력 길이 시작 오프셋을, message_length은 사용자 입력 길이를 의미하는 매개변수이다. 사용자 입력에 대한 암호문 출력 바이트를 반환하는 함수이며, pbszUserKey와 pbszIV의 크기는 각각 16바이트이어야 한다. | ||
+ | # public static byte[] SEED_CBC_Decrypt( byte[] pbszUserKey, byte[] pbszIV, byte[] message, int message_offset, int message_length ) : SEED-CBC 알고리즘 복호화 함수이다. pbszUserKey는 사용자가 지정하는 16바이트 입력 키를, pbszIV 는 사용자가 지정하는 16바이트 초기화 벡터를 의미한다. message는 사용자 입력 평문을, message_offset은 사용자 입력 길이 시작 오프셋을, message_length은 사용자 입력 길이를 가리키는 매개변수이다. 위와 같이 사용자 입력에 대한 평문 출력 바이트를 반환하는 함수로, pbszUserKey와 pbszIV의 크기는 각각 16바이트이어야 한다. | ||
+ | # public static int SEED_CBC_init( KISA_SEED_INFO pInfo, KISA_ENC_DEC enc, byte[] pbszUserKey, byte[] pbszIV ) : SEED-CBC 알고리즘 초기화 함수이다. pInfo는 SEED CBC 알고리즘 운영을 위한 클래스를 지정하고, enc는 알고리즘 암호화 및 복호화 모드를 지정하는 매개변수이다. pbszUserKey는 사용자가 지정하는 16바이트 입력 키이고, pbszIV는 사용자가 지정하는 16바이트 초기화 벡터이다. 반환값으로 0과 1을 가지며, 1을 반환했다면 초기화에 성공한 것이고, 0을 반환했다면 초기화에 실패했다는 뜻이다. | ||
+ | # public static int SEED_CBC_Process( KISA_SEED_INFO pInfo, int[] in, int inLen, int[] out, int[] outLen ): SEED-CBC 알고리즘 다중 블록 암호화 함수이다. pInfo는 SEED CBC 알고리즘 운영을 위해 클래스를 지정하는 매개변수이며, in은 사용자 입력 평문 및 암호문을 의미한다. inLen은 사용자 입력의 길이 지정을, out은 사용자 입력에 대한 암호문 및 평문 출력 버퍼를 의미한다. outLen은 출력 버퍼에 저장된 데이터의 길이를 의미하는 매개변수이다. 0과 1을 반환하며, 1을 반환했다면 구동하는 데 성공한 것이고, 0을 반환했다면 구동에 실패한 것이다. | ||
+ | # public static int SEED_CBC_Close( KISA_SEED_INFO pInfo, int[] out, int out_offset, int[] outLen ) : SEED-CBC 알고리즘 운영 모드 종료 및 패딩(PKCS7) 처리 함수이다. pInfo는 SEED CBC 알고리즘 운영을 위한 클래스를 지정하고, out은 사용자 입력에 대한 최종 출력 블록이 저장되는 버퍼를 말한다. out_offset은 출력 버퍼의 시작 오프셋이며, outLen은 출력 버퍼에 저장된 데이터의 길이를 가리킨다. 반환값으로는 0과 1을 가지는데, 1인 경우에는 패딩에 성공한 것이고, 0인 경우에는 패딩에 실패했다는 뜻이다. | ||
+ | |||
+ | * '''SEED-CTR''' | ||
+ | # public static byte[] SEED_CTR_Encrypt( byte[] pbszUserKey, byte[] pbszCTR, byte[] message, int message_offset, int message_length ) | ||
+ | # public static byte[] SEED_CTR_Decrypt( byte[] pbszUserKey, byte[] pbszCTR, byte[] message, int message_offset, int message_length ) | ||
+ | # public static int SEED_CTR_init( KISA_SEED_INFO pInfo, KISA_ENC_DEC enc, byte[] pszUserKey, byte[] pbszCTR ) | ||
+ | # public static int SEED_CTR_Process( KISA_SEED_INFO pInfo, int[] in, int inLen, int[] out, int[] outLen ) | ||
+ | # public static int SEED_CTR_Close( KISA_SEED_INFO pInfo, int[] out, int out_offset, int[] outLen ) | ||
+ | |||
+ | * '''SEED-CCM''' | ||
+ | # public int SEED_CCM_Encryption(byte[] ct, byte[] pt, int ptLen, int macLen, byte[] nonce, int nonceLen, byte[] aad, int aadLen, byte[] mKey) | ||
+ | # public int SEED_CCM_Decryption(byte[] pt, byte[] ct, int ctLen, int macLen, byte[] nonce, int nonceLen, byte[] aad, int aadLen, byte[] mKey) | ||
+ | |||
+ | * '''SEED-GCM''' | ||
+ | # public int SEED_GCM_Encryption(byte[] ct, byte[] pt, int ptLen, int macLen, byte[] nonce, int nonceLen, byte[] aad, int aadLen, byte[] mKey) | ||
+ | # public int SEED_GCM_Decryption(byte[] pt, byte[] ct, int ctLen, int macLen, byte[] nonce, int nonceLen, byte[] aad, int aadLen, byte[] mKey) | ||
+ | |||
+ | * '''SEED-CMAC''' | ||
+ | # public int SEED_Generate_CMAC(byte[] pMAC, int macLen, byte[] pIn, int inLen, byte[] mKey) | ||
+ | # public int SEED_Verify_CMAC(byte[] pMAC, int macLen, byte[] pIn, int inLen, byte[] mKey)<ref name='시드 매뉴얼'></ref> | ||
+ | |||
+ | == 그 외의 알고리즘 == | ||
+ | :{|class=wikitable width=1000 style="background-color:#ffffee" | ||
+ | |+<big>'''국내외 암호화 알고리즘(2017년 기준)'''</big> | ||
+ | !align=center style="background-color:#ffeecc"|분류 | ||
+ | !align=center style="background-color:#ffeecc"|미국(NIST) | ||
+ | !align=center style="background-color:#ffeecc"|일본(CRYPTREC) | ||
+ | !align=center style="background-color:#ffeecc"|유럽(ECRYPT) | ||
+ | !align=center style="background-color:#ffeecc"|국내 | ||
+ | |- | ||
+ | |align=center style="background-color:#ffeecc"|대칭키 암호 알고리즘 | ||
+ | |align=center|AES-128/192/256 3TDEA | ||
+ | |align=center|AES-128/192/256 3TDEA Camellia-128/192/256 MISTY1 | ||
+ | |align=center|AES-128/192/256 Blowfish KASUMI 3TDEA | ||
+ | |align=center|SEED, HIGHT, ARIA-128/192/256 | ||
+ | |- | ||
+ | |align=center style="background-color:#ffeecc"|공개키 암호 알고리즘(메시지 암/복호화) | ||
+ | |align=center|RSA(사용 권고하는 키 길이 확인 필요) | ||
+ | |align=center|RSAES-OAEP RSAES-PKCS1 | ||
+ | |align=center|RSAES-OAEP RSAES-PKCS1 | ||
+ | |align=center|RSAES-OAEP | ||
+ | |- | ||
+ | |align=center style="background-color:#ffeecc"|일방향 암호 알고리즘 | ||
+ | |align=center|SHA-224/256/384/512 | ||
+ | |align=center|SHA-256/384/512 | ||
+ | |align=center|SHA-224/256/384/512 Whirlpool | ||
+ | |align=center|SHA-224/256/384/512 | ||
+ | |} | ||
+ | |||
+ | === 국내 === | ||
+ | * '''ARIA'''(Academy Research Institute Agency) : 전자정부 구현 등으로 다양한 환경에 적합한 암호화 알고리즘의 필요성이 대두됐고, 이에 따라 국가보안기술연구소 주도로 학계와 국가 정보원 등의 암호기술 전문가들이 힘을 모아서 개발한 국가 암호화 알고리즘이다. ISPN 구조의 128비트 블록 암호이며, 128비트, 192비트, 256비트 세 가지 키를 제공한다. 이들 각각은 키 길이에 따라 ARIA-128, ARIA-192, IRIA-256으로 구분한다. ARIA의 입출력 크기와 사용 가능한 키 크기는 미국 표준 블록 암호인 AES와 동일하다. | ||
+ | |||
+ | * '''HIGHT'''(HIGH security and light weightT) : RFID, USN 등과 같이 저전력과 저경량을 요구하는 컴퓨팅 환경에서 기밀성을 제공하기 위해 개발된 64비트 블록 암호이다. | ||
+ | |||
+ | * '''LEA'''(Lightweight Encryption Algorithm) : 128비트 경량 고속 블록 암호 알고리즘이다. AES보다 1.5에서 2배는 빠르다. 다양한 정보보안 서비스에서 다양한 데이터를 빠르게 처리할 수 있고, 스마트폰의 보안과 사물 인터넷 등의 저전력 암호화에도 널리 사용할 수 있다. | ||
+ | |||
+ | === 국외 === | ||
+ | * '''IDEA'''(International Data Encrption Algorithm) | ||
+ | :DES를 대체하기 위하여 스위스의 한 연방기술 기관에서 개발한 알고리즘이다. 128비트 키, 64비트 블록 암호로 파이스텔 구조를 변형했다. 파이스텔과 SPN의 중간 형태이다. 8라운드를 걸쳣 데이터를 변환하며, 마지막에 한 번 더 키를 적용해 64비트 암호문을 생성하기 때문에, 보통 8.5라운드라고도 부른다. IDEA는 DES와는 달리 S-box를 사용하지 않고 대수적 구조가 서로 다른 연산을 번갈아 사용해서 암호학적인 강도를 높였다. PGP의 데이터 암호 알고리즘으로 채택되어 사용되고 있으며, DES보다 2배 정도 빠르고 무차별 공격에 더욱 효율적으로 대응한다. | ||
+ | |||
+ | * '''RC5'''(Ron's Code 5) : 1994년, 미국의 RSA 연구소의 라이베스트가 개발했다. 비교적 간단한 연산으로 빠른 암호화와 복호화 기능을 제공할 수 있는 알고리즘으로, 모든 하드웨어에 적합한 편이다. 입출력과 키, 라운드 수가 가변인 블록 알고리즘이며, 32/64/128비트의 블록을 갖고 있고, 속도는 DES의 약 10배이다. 간단한 알고리즘과 빠른 속도가 특징이다. | ||
+ | |||
+ | * '''DES''' : 미국 연방정부(NIST)에서 1977년 표준으로 공표, 16라운드의 알고리즘이며, 블록은 64비트 크기이다. | ||
+ | * '''AES''' : 미국 연방정부에서 표준으로 공표, 128/192/256 비트키 | ||
+ | * '''FEAL''' : 소프트웨어 구현에 적합하다. 64/128비트 블록크기<ref> 와이준 Nye, 〈[https://yjshin.tistory.com/entry/%EC%95%94%ED%98%B8%ED%95%99-%EA%B8%B0%ED%83%80-%EB%8C%80%EC%B9%AD%ED%82%A4-%EC%95%94%ED%98%B8-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-IDEA-RC5-SEED-ARIA-HIGHT-LEA (암호학) 기타 대칭키 암호 알고리즘 - IDEA, RC5, SEED, ARIA, HIGHT, LEA]〉, 《티스토리》, 2019-11-19 </ref><ref> ojava, 〈[https://ojava.tistory.com/103 KISA 권고 암/복호화 방식:SEED 128, SEED 256]〉, 《티스토리》, 2017-05-15 </ref> | ||
+ | |||
+ | {{각주}} | ||
+ | |||
+ | ==참고자료== | ||
+ | * SEED 위키백과 - https://ko.wikipedia.org/wiki/SEED | ||
+ | * SEED 나무위키 - https://namu.wiki/w/SEED | ||
+ | * 한국인터넷진흥원 공식홈페이지 SEED - https://seed.kisa.or.kr/kisa/algorithm/EgovSeedInfo.do | ||
+ | |||
+ | * 한국인터넷진흥원, 〈[SEED 128 알고리즘 상세 명세서]〉, 《한국인터넷진흥원》, 2009-07 | ||
+ | * ojava, 〈[https://ojava.tistory.com/103 KISA 권고 암/복호화 방식:SEED 128, SEED 256]〉, 《티스토리》, 2017-05-15 | ||
+ | * 관리자1, 〈[https://seed.kisa.or.kr/kisa/Board/17/detailView.do 암호알고리즘 소스코드]〉, 《한국인터넷진흥원》, 2019-01-31 | ||
+ | * 와이준 Nye, 〈[https://yjshin.tistory.com/entry/%EC%95%94%ED%98%B8%ED%95%99-%EA%B8%B0%ED%83%80-%EB%8C%80%EC%B9%AD%ED%82%A4-%EC%95%94%ED%98%B8-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-IDEA-RC5-SEED-ARIA-HIGHT-LEA (암호학) 기타 대칭키 암호 알고리즘 - IDEA, RC5, SEED, ARIA, HIGHT, LEA]〉, 《티스토리》, 2019-11-19 | ||
+ | |||
+ | == 같이 보기 == | ||
+ | * [[AES]] | ||
+ | * [[DES]] | ||
+ | * [[ARIA]] | ||
+ | * [[대칭키]] | ||
+ | * [[공개키]] | ||
+ | |||
+ | {{암호 알고리즘|검토 필요}} |
2023년 8월 1일 (화) 14:04 기준 최신판
SEED 또는 시드 블록 암호 알고리즘은 전자상거래, 금융, 무선통신 등에서 전송되는 개인정보와 같은 중요한 정보를 보호하기 위해, 1999년 2월 한국인터넷진흥원과 국내 암호전문가들이 순수 국내기술로 개발한 128비트 및 256비트 대칭 키 블록의 암호 알고리즘이다. 미국에서 수출하는 웹브라우저 보안의 수준이 40비트로 제한함으로써 128비트 보안을 위해서 자국에서 개발한 별도의 알고리즘이다.
목차
개요[편집]
시드 블록 암호 알고리즘은 민간 부분인 인터넷, 전자상거래, 무선 통신 등에서 공개 시 민감한 영향을 미칠 수 있는 정보의 보호와 개인 프라이버시 등을 보호하기 위하여 1992년 2월 한국 정보보호센터(KISA)에 의해 개발된 대칭키 암호 알고리즘이다. 대칭키 블록 암호 알고리즘으로 비밀성을 제공하는 암호시스템의 중요 요소이다. 블록 암호 알고리즘 SEED는 128비트의 비밀키를 이용해 128비트의 평문을 암호문으로 변환한다. 금융권, 전자상거래, 정보 보호 제품(VPN) 등의 다양한 분야에서 데이터의 기밀성과 무결성 기능을 제공하기 위해 사용되고 있다. 국외 주요 정보 보호 업체를 포함한 670개 이상의 국내 외 산업계와 학계와 연구 분야에서 SEED를 사용하고 있다. 블록 암호 알고리즘의 경우, 암호 알고리즘이 적용되는 블록 크기가 정해져 있기 때문에 정해진 길이보다 긴 데이터를 암호화하거나 데이터 무결성 검증을 하기 위해서는 블록 암호 알고리즘의 운영 모드를 반드시 사용하게 된다. 입력 데이터의 길이가 기본 블록 크기의 배수가 되지 않으면 처리가 불가능하므로 입력 메시지의 길이가 기본 블록 크기의 배수가 되지 않으면 처리가 불가능해 입력 메시지의 길이가 블록 길이의 배수가 되도록 하기 위해 덧붙이기 방법을 사용해야 한다. 이에, 한국 정보보호진흥원에서는 안전성 측면과 효율성 측면을 고려하여 SEED의 사용을 촉진하기 위해 SEED의 운영 모드를 TTA 표준으로 제안하여 2003년 12월 TTA 표준으로 제정하였다. 128비트 블록 암호 SEED를 국민이 쉽게 활용할 수 있도록 ECB, CBC, CTR, CCM, GCM, CMAC 운영 모드에 대한 소스 코드를 배포하고 있다. 배포하는 소스 코드의 언어는 C 언어, C++, 자바, ASP, JSP, PHP로 구성된다.
역사[편집]
- 1999년 2월 한국 인터넷진흥원과 국내 암호전문가들이 개발
- 1999년 9월 정보통신 단체표준(TTA)으로 제정
- 2005년 국제 표준화 기구인 ISO/IEO 국제 블록 암호 알고리즘, IETF 표준으로 제정
- 2009년 256비트 키를 지원하는 SEED 256 개발
구조[편집]
SEED 알고리즘은 전체적으로 파이스텔(Feistel) 구조로 이루어져 있다. 128비트의 평문 블록과 128비트 키를 입력으로 사용해서 총 16라운드에 걸쳐 128비트 암호문 블록을 출력한다.
F함수[편집]
파이스텔 구조 형태인 블록 암호 알고리즘은 F 함수의 특성에 따라서 구분될 수 있다. SEED의 F 함수는 수정된 64피트 파이스텔 형태로 구성되는데, 각 32비트 블록 2개를 입력받아서 32비트 블록 2개를 출력한다. 즉, 전자의 경우를 C와 D라고 하고 후발대는 C'와 D'라고 할 때, 암호화 과정에서 64비트 블록인 C, D와 64비트 라운드 키 를 F 함수의 입력으로 처리해서 64비트 블록인 C'와 D'를 출력한다. 참고로 여기서 i란 라운드 수를 의미한다.
G 함수[편집]
전체 G 함수는 다음과 같이 기술된다.
참고로 위의 G 함수는 구현의 효율성을 위하여 4개의 확장된 4바이트 SS-box들의 배타적 논리합으로 구현할 수 있다. 그러기 위해선 다음과 같이 4개의 SS-box들을 저장해야 한다.
이 확장 SS-box들을 이용하면 G 함수는 다음처럼 구현할 수 있다.
S-Box[편집]
G 함수의 내부에 사용되는 비선형 S-box 을 생성하기 위해 다음 식이 사용되었다.
라운드 키 생성과정[편집]
SEED의 라운드 키를 생성하는 과정은 우선 128비트 암호키를 64비트씩 좌우로 나누어서 이들을 8비트씩 교대로 좌우로 회전이동한다. 그 후, 결과의 4워드들에 대해 간단한 산술 연산과 G 함수를 적용해서 라운드 키를 생성한다. 라운드 키 생성 과정은 기본적으로 하드웨어나 제한된 자원을 가지는 스마트카드 같은 곳에서 효율적으로 응용할 수 있도록 만들기 위해, 암호화나 복호화를 진행할 때 암호키에서 필요한 라운드 키를 간단하게 계산할 수 있도록 설계되었다.
주어진 128비트 암호키가 K=A||B||C||D일 때, 해당 암호키를 32비트 레지스터인 A, B, C, D로 나눈다. 각 라운드 i 에 사용되는 키 K_i=(K_{i,0}:K_{i,1})는 다음과 같은 방식으로 생성한다.[1]
{ }
라운드키 생성과정에 사용된 상수 라운드 상수 = 0x9e3779b9 = 0x3779b99e = 0x3c6ef373 = 0x6ef3733c = 0x78dde6e6 = 0xdde6e678 = 0xf1bbcdcc = 0xbbcdccf1 = 0xe3779b99 = 0x779b99e3 = 0xc6ef3733 = 0xef3733c6 = 0x8dde6e67 = 0xde6e678d = 0x1bbcdccf = 0xbcdccf1b
특징[편집]
표준화 현황[편집]
SEED는 1999년 9월 정보통신단체 표준으로 제정되었고, 2005년에는 국제 표준화 기구인 ISO/IEC 국제 블록 암호 알고리즘 IETF 표준으로 제정되었다. 국내외의 표준명은 각각 다음과 같다.
- 국내 : TTAS.KO-12.0004/R1 : 128비트 블록 암호 알고리즘(SEED)
- 국외 : ISO/IEC 18033-3 : 정보기술보안기술(Information technology Security techniques), 암호화(Encryption), Part 3 : Block ciphers, IETF RFC 4269 : SEED 암호화 알고리즘(The SEED Encryption Algorithm) 4가지가 있으며, RFC4269은 RFC 4009 (The SEED Encryption Algorithm)의 개정 표준이다.
SEED 암호 알고리즘 자체에 대한 표준 외에도 SEED를 사용하기 위한 다양한 국내외 표준들도 제정되었다. 이에 해당하는 국내외 표준명은 다음과 같다.
- 국내 : TTAS.KO-12.0025 : 블록 암호 알고리즘 SEED의 운영 모드
- 국외 : IETF RFC 4010 : 보안 전자우편에서의 메시지 암호화를 위한 SEED 사용표준, IETF RFC 4162 : TLS를 위한 SEED 알고리즘 사용표준, IETF RFC 4196 : IPsec을 위한 SEED 알고리즘 사용표준[2]
보급 신청[편집]
- 지식재산권 : 한국인터넷진흥원은 SEED를 이용한 제품의 생산이나 판매와 관련된 지식재산권에 대하여 별도의 사용료를 요구하지 않는다.
- 소스 코드: SEED는 전자상거래, 이메일, 인터넷뱅킹, 데이터 저장, VPN, 지식재산권 보호 등의 다양한 분야에서 사용될 수 있고, 사용되고 있다. 한국인터넷진흥원은 2009년 5월 말 기준, nCipher, RSA Security 등의 국외 정보보호 업체들을 포함하여 총 3,232개 이상의 국내외 기업 및 학교에 SEED 소스 코드를 이메일을 이용하여 전달했다. 현재 배포하고 있는 SEED 소스 코드는 32비트 프로세서에 맞도록 C언어와 자바 언어로 구현되었다.[2]
블록 암호 알고리즘[편집]
암호는 허락받지 않은 제삼자가 메시지를 해독할 수 없도록 상태를 변환하거나 암호화된 메시지를 해독할 수 있도록 변환하는 기술이다. 이 과정에서 해독 가능한 형태로 바꾸는 과정 복호화라고 부르며, 반대로 해독할 수 없는 상태로 바꾸는 과정은 암호화라고 칭한다. 또한, 해독할 수 있는 형태의 메시지는 평문이라고 부르며, 해독할 수 없는 상태의 메시지는 암호문이라고 한다. 정보를 숨기고 숨긴 정보를 읽고 해석하기 위해선 권한이 있는 사람만이 암호화와 복호화를 진행할 수 있어야 하므로, 이러한 비밀 정보는 비밀키라고 불리며, 암호화에 필요한 암호화 키와 복호화에 필요한 복호화키로 분류한다. 암호는 키의 특성에 따라 암호화 키와 복호화키가 같은 암호를 대칭키암호 또는 비밀키 암호라고 하는데, 암호화 키와 복호화키가 다른 암호는 비대칭 키 암호 또는 공개키 암호라고 부른다. 또한, 대칭키 암호는 다시 암호화 및 복호화 처리를 하는 방법에 따라, 메시지를 블록 단위로 나누어서 처리하는 블록 암호와 메시지를 비트 단위로 처리하는 스트림 암호로 분류한다. SEED는 128비트의 암호화 복호화 키를 사용해서 임의의 길이를 갖는 입력 메시지를 128비트의 블록 단위로 처리하는 128비트 블록 암호 알고리즘에 해당하며, 따라서 임의의 길이를 가지는 평문 메시지를 128비트씩 블록 단위로 나누고 암호화하고 암호문을 생성하여 소프트웨어 및 하드웨어의 보안에 기여한다.[3]
고려사항[편집]
SEED를 실제로 사용하기 위해서는 구현 환경에서 사용되는 엔디안(Endianness)과 암호화된 데이터가 저장되는 데이터 형식을 고려해야 한다. 또한, 입력 블록을 블록 암호에 적용하는 방법인 운영 모드와 마지막 블록의 크기를 맞추기 위한 패딩을 함께 구현해 주어야 한다.
엔디안[편집]
컴퓨터 메모리의 바이트를 배열하는 순서를 엔디안이라고 부른다. 엔디안은 보통 큰 단위가 앞에 나오는 빅 에디안, 작은 단위가 앞에 나오는 리틀 엔디안, 두 경우에 속하지 않거나 둘 모두를 지원하는 미들 엔디안으로 분류된다. 현재 빅 엔디안과 리틀 엔디안이 많이 사용되지만, 일반적인 데스크탑에서는 x86 아키텍처를 많이 사용하고 있고 x86 아키텍처는 리틀 엔디안 구조를 사용하기 때문에, 한국인터넷진흥원에서는 기본적으로 리틀 엔디안을 적용한 SEED 소스 코드를 배포하고 있다. 엔디안은 암호 알고리즘을 구현할 때 중요하게 고려해야 할 문제 중 하나인데, 대부분의 암호 알고리즘은 비트 단위로 연산을 처리하기 때문에 바이트 배열이 서로 맞지 않으면 같은 알고리즘으로 같은 메시지를 암호화하더라도 서로 다른 암호문을 생성할 수 있다. 자바 가상머신은 기본적으로 빅 엔디안은 사용하기 때문에 자바 소스 코드에서는 엔디안에 기본적으로 빅 엔디안이 설정되어 있는데, 상황에 따라 사용자는 시스템의 엔디안에 맞게 수동으로 선택해 주어야만 한다.
데이터 형식[편집]
일반적으로 암호 알고리즘은 비트 단위의 연산을 포함한 다양한 연산을 수행해서 평문 메시지를 무의미한 비트열인 암호문으로 변환한다. 여기서 만들어진 암호문 비트열은 반복이 없는 무작위에 의한 비트들로 구성되기 때문에 이를 문자열 형태로 저장하거나 처리할 때는 문제가 발생할 수 있다. 따라서 암호화된 메시지는 항상 문자열이 아니라 이진 형태로 처리해야 한다. 다음과 같이 C 언어 코드로 만든 예시가 있다고 하자. ch 배열에 저장되는 값은 0x41, 0x42, 0x00, 0x44, 0x45지만, 만약 이를 문자열로 출력한다면 ch[3] = 0x00 = NULL 값으로 인해 0x41, 0x42에 해당하는 'AB'만 출력된다. 따라서 암호화된 메시지는 항상 문자열이 아니라 HEX 형태로 처리해야 한다.
char ch[ ] = {0x41, 0x42, 0x00, 0x44, 0x45}; printf("%s", ch);
운영 모드[편집]
운영 모드는 여러 개의 입력 블록들을 블록 암호에 적용해서 암호화 및 복호화하는 방법에 대한 정의를 말한다. 이러한 운영 모드는 블록 암호와는 독립적으로 정의되는데, 대표적으로 가장 널리 이용되는 블록 암호의 기밀성 운영 모드에는 ECB 모드, CBC 모드, CFB 모드, OFB 모드, CTR 모드가 있고, 인증 운영 모드에는 CMAC 모드, 인증 암호화 운영 모드에는 CCM 모드, GCM 모드가 있다. 다음은 이 중 ECB, CBC, CTR, CCM, GCM, CMAC 모드에 대한 설명이다.
- ECB 운영 모드
- ECD 모드는 평문 블록을 암호문 블록으로 독립적으로 암호화하는 운영 모드이다. 암호화 과정은 평문 블록을 입력 블록으로 설정하고, 이를 암호화한 출력 블록을 암호문 블록으로 설정한다. 복호화 과정은 평문 블록을 입력 블록으로 설정하고, 이를 암호화한 출력 블록을 암호문 블록으로 설정한다.
- CBC 운영 모드
- CBC 모드는 동일한 평문 블록과 암호문 블록 쌍이 발생하지 않도록 전 단계의 암호화 및 복호화 결과가 현 단계에 영향을 주는 운영 모드이다. CBC 모드의 암호화 과정은 현 단계에서 평문 블록과 전 단계의 암호문 블록을 배타적 논리합 연산한 결과를 현 단계의 입력 블록으로 설정하고, 이를 암호화한 출력 블록을 현 단계의 암호문 블록으로 설정한다. 복호화 과정은 현 단계의 암호문 블록을 입력 블록으로 설정한 후, 이를 복호화한 출력 블록을 전 단계의 입력 블록인 암호문 블록과 배타적 논리합 연산한 결과를 현 단계의 평문 블록으로 한다.
- CTR 운영 모드
- CTR 모드는 각 단계에 따라 증가하는 카운트 블록을 입력 블록으로 사용하는 운영 모드이다. 암호화 과정은 카운터를 현 단계의 입력 블록으로 해서 암호화한 출력 블록을 평문 블록과 배타적 논리합 연산을 수행해서 암호문 블록을 생성한다. 복호화 과정은 카운터를 현 단계의 입력 블록으로 하고, 암호화한 출력 블록을 암호문 블록과 배타적 논리합 연산을 수행해서 평문 블록을 생성한다.
- CCM 운영 모드
- CCM 운영 모드는 CTR 모드에 CBC-MAC의 메시지 인증을 포함한 128비트 전용 운영 모드이다. CCM 모드의 암호화 과정은 입력 데이터로부터 데이터 블록 열과 초기 카운터 블록을 생성하는 것부터 시작한다. 데이터 블록 열은 CBC-MAC의 출력값을 얻는 데 사용되고, 인증값은 초기 카운터 블록에 의한 암호화 함수의 출력 블록과 CBC-MAC 출력값의 XOR 결과를 최상위 비트부터 주어진 인증값 길이만큼 절삭한 값으로 설정한다. 그리고 CTR 모드를 통해 평문에 대한 암호문을 생성한다. 최종 출력은 CTR 모드에서 얻어진 암호문과 CBC-MAC에서 얻어진 인증값을 연접한 결과이다. CCM 모드의 복호화 과정은 입력 데이터에서 초기 카운터 블록을 생성하는 것부터 시작한다. 초기 카운터 블록에 대한 암호화 함수 출력 블록은 입력 데이터에 포함된 인증값과 XOR 하는데, 그 결과는 마지막 단계에서 CBC-MAC의 출력값과 비교하는 데 사용된다. 이어서 암호문에 대한 평문은 CTR 모드를 통해 생성된다. 데이터 블록 열을 생성한 후에, 이에 대한 CBC-MAC의 출력값을 최상위 비트부터 주어진 인증값 길이만큼 절삭하여 인증값으로 설정한다. 마지막으로 복호화 과정에서 계산된 인증값과 입력 데이터에 포함된 인증값을 비교하여, 일치한다면 평문을 출력하고 그렇지 않다면 오류 플래그를 출력한다.
- GCM 운영 모드
- GCM 모드는 CTR 모드에 유한체 상의 곱 연산을 이용한 메시지 인증을 포함한 128비트 전용 운영 모드이다. GCM의 암호화 과정은 먼저 인증값 계산에 사용할 보조 비밀키와 초기 카운터 블록을 생성하는 것부터 시작한다. 그리고 하위의 32비트에 대해서 1 증가시킨 카운터 블록을 초깃값으로 해서 CTR 모드를 통해 평문에 대한 암호문을 생성한다. 암호문과 부가 인증 데이터는 정해진 함수의 출력값을 얻는 데 사용되며, 인증값은 초기 카운터에 대한 암호화 함수의 출력 블록과 정해진 함수 출력의 XOR 결과를 최상위 비트부터 주어진 인증값 길이만큼 절삭한 값으로 설정한다. 최종 출력은 CTR 모드로부터 얻어진 암호문과 정해진 함수에서 얻어진 인증값을 연접한 결과이다. GCM의 복호화 과정은 먼저 인증값 계산에 사용할 보조 비밀키와 초기 카운터 블록을 생성하는 것부터 시작한다. 그리고 하위의 32비트에 대해 1 증가시킨 카운터 블록을 초깃값으로 한 CTR 모드를 통해서 암호문에 대한 평문을 생성한다. 이어서 인증값은 초기 카운터에 대한 암호화 함수의 출력 블록과 정해진 함수 출력의 XOR 결과를 최상위 비트부터 주어진 인증값 길이만큼 절삭한 값으로 설정한다. 마지막으로 복호화 과정에서 계산된 인증값과 입력 데이터에 포함된 인증값을 비교해서, 일치한다면 평문을 출력하고 그렇지 않다면 오류 플래그를 출력한다.
- CMAC 운영 모드
- CMAC는 CBC 모드에서 파생된 메시지 인증 방식 CBC-MAC을 안전성 측면에서 개선한 운영 모드이다. CMAC의 인증값 생성 과정은 먼저 메시지를 b 비트 단위로 분할하고, 분할된 각 블록을 차례대로 로 표시한다. 여기서 블록 의 길이는 b 비트 이하이다. 그리고 (m-1)개의 메이지 블록 열 에서 현재 단계의 메시지 블록과 직전 단계 블록 암호 암호화 함수 출력 블록의 XOR 결과를 암호화 함수의 입력 블록으로 설정해서 현재 단계 출력 블록을 얻는 구성을 반복한다. 마지막 메시지 블록(M_m^*)을 처리할 때 해당 메시지 블록의 길이가 b비트인가 여부에 따라서 비밀키 K로부터 생성한 보조 비밀키와 직전 단계 암호화 함수 출력 블록, 그리고 메시지 블록(M_m^*)의 XOR 결과를 블록 암호 암호화 함수 입력 블록으로 설정한다. 이렇게 얻은 블록 암호 암호화 함수 출력 블록의 상위 비트를 인증값으로 설정한다. 수신한 메시지 M과 인증값 T가 유효한지를 검증하기 위해서 비밀키 K를 사용해서 직접 인증값 을 계산한 후, 여부를 확인한다.
패딩[편집]
메시지를 HIGHT에 입력하기 위해 여러 개의 64비트 블록으로 나눌 때, 마지막 블록을 정확히 64비트 블록으로 크기를 맞추는 일은 현실적으로 쉽지 않고 어려운 일이다. 예를 들어 300비트짜리 메시지를 64비트의 블록으로 나눈다고 할 때, 130=64+64+2로 나누어서 세 개의 블록을 구성하게 되는데, 이때 마지막 블록이 2비트로 64비트를 만족하지 못한다. 이 경우에 나머지 부족한 62비트를 채워주어야만 HIGHT의 입력값으로 사용이 가능하다. 이렇게 부족한 부분을 채우는 방식을 바로 패딩이라고 일컫는다. ECB, CBC 모드는 평문 블록을 암호화의 입력으로 사용하고, 평문 데이터의 크기가 64비트의 양의 정수배가 되어야 하므로 반드시 덧붙이기 방법이 적용해야 한다. 그러나 CFB-s, OFB, CTR 모드의 경우에는 마지막 암호화 단계의 평문 블록이 64비트를 만족하지 못하고, CFB-s 모드의 경우에는 s를 만족하지 못하고 m비트가 남아있을 때, 마지막 출력 블록인 64비트 중 상위의 m비트와 마지막 평문 블록 m비트와 배타적 논리합 연산 합으로 다음과 같은 덧붙이기 방법을 적용하지 않을 수도 있다. 다음에 설명할 패딩 방법들은 ISO/IEC 국제표준 및 PKCS에서 사용하는 방법이기도 하며, 적용되는 시스템에 맞도록 사용함을 권고하고 있다. 그러나 패딩 방법 1의 경우에는 복호화된 평문 데이터의 크기가 명확하지 않은 경우가 일어나기 때문에 평문 데이터의 크기가 명확히 알려진 경우에만 사용할 것을 권고하고 있다.
- 패딩 방법 1
- 평문 데이터의 크기가 64비트 양의 정수배가 아닐 경우, 마지막 평분 블록이 64비트가 되도록 바이트 '00'을 덧붙인다.
입력 블록( 48비트) : 4F 52 49 54 48 4D 패딩 블록(128비트) : 4F 52 49 54 48 4D 00 00 00 00 00 00 00 00 00 00 입력 블록(128비트) : 53 45 45 44 41 4C 47 A8 3E D1 80 F1 29 DC 4A 78 패딩 블록(128비트) : 53 45 45 44 41 4C 47 A8 3E D1 80 F1 29 DC 4A 78
- 패딩 방법 2
- 평문 데이터의 크기가 64비트의 양의 정수배가 아닌 경우, 마지막 평문 블록이 64비트가 되도록 평문 데이터의 끝에 비트 '80'을 추가하고, 나머지는 모두 '0'비트를 덧붙인다. 그리고 평문 블록의 크기가 64비트의 양의 정수배일 경우에는 추가적인 128비트 '80...00' 블록을 추가한다.
입력 블록( 48비트) : 4F 52 49 54 48 4D 패딩 블록(128비트) : 4F 52 49 54 48 4D 80 00 00 00 00 00 00 00 00 00 입력 블록(128비트) : 53 45 45 44 41 4C 47 A8 3E D1 80 F1 29 DC 4A 78 패딩 블록(256비트) : 53 45 45 44 41 4C 47 A8 3E D1 80 F1 29 DC 4A 78 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 패딩 방법 3
- 평문 데이터의 크기가 128비트 양의 정수배가 아닌 경우에는, 마지막 평문 블록이 128비트가 되도록 덧붙이기가 필요한 바이트 수 'xx...xx'를 덧붙인다. 그리고 평문 블록의 크기가 128비트의 양의 정수배인 경우에는 추가적인 128비트 '0F...0F' 블록을 추가한다.
입력 블록( 48비트) : 4F 52 49 54 48 4D 패딩 블록(128비트) : 4F 52 49 54 48 4D 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 입력 블록(128비트) : 53 45 45 44 41 4C 47 A8 3E D1 AF 07 4A 73 12 2C 패딩 블록(256비트) : 53 45 45 44 41 4C 47 A8 3E D1 AF 07 4A 73 12 2C 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F
활용 방법[편집]
메시지를 HIGHT에 입력하기 위해서 여러 개의 64비트 블록으로 나눌 때, 마지막 블록을 정확히 64비트의 블록 크기로 맞추기는 어렵다. 예를 들어, 300비트의 메시지를 64비트의 블록으로 나눈다고 하면 130=64+64+2로 나누어서 세 개의 블록을 구성하게 된다. SEED 알고리즘은 16바이트의 비밀키, 16바이트의 평문을 입력으로 16바이트의 암호문을 출력하는 블록 암호 알고리즘이다. 한국인터넷진흥원에서 제공하는 소스 코드에는 두 가지 방법의 함수가 포함되어 있다. 첫 번째 방법은 처리하고자 하는 데이터가 적을 경우에 쓰이는 방법으로, Encrypt와 Decrypt 함수만 호출하면 암호화와 복호화가 된다. 두 번째 방법은 대용량의 데이터를 암호화 및 복호화할 때 3가지 단계로 데이터 크기가 버퍼보다 클 경우 사용되는 방법이다.[3]
소스 코드[편집]
C/C++[편집]
- SEED-ECB
- void SEED_KeySched( DWORD *pdwRoundKey, BYTE *UserKey );
- void SEED_Encrypt( BYTE *pbData, DWORD *pdwRoundKey );
- void SEED_Decrypt( BYTE *pbData, DWORD *pdwRoundKey );
- SEED-CBC
- int SEED_CBC_Encrypt( IN BYTE *pbszUserKey, IN BYTE *pbszIV, IN BYTE *pbszPlainText, IN int nPlainTextLen, OUT BYTE *pbszCipherText )
- int SEED_CBC_Decrypt( IN BYTE *pbszUserKey, IN BYTE *pbszIV, IN BYTE *pbszCipherText, IN int nCipherTextLen, OUT BYTE *pbszPlainText )
- int SEED_CBC_init( OUT KISA_SEED_INFO *pInfo, IN KISA_ENC_DEC enc, IN BYTE *pbszUserKey, IN BYTE *pbszIV )
- int SEED_CBC_Process( OUT KISA_SEED_INFO *pInfo, IN DWORD *in, IN int inLen, OUT DWORD *out, OUT int *outLen )
- int SEED_CBC_Close( OUT KISA_SEED_INFO *pInfo, IN DWORD *out, IN int *outLen )
- SEED-CTR
- int SEED_CTR_Encrypt( IN BYTE *pbszUserKey, IN BYTE *pbszIV, IN BYTE *pbszPlainText, IN
- int nPlainTextLen, OUT BYTE *pbszCipherText )
- int SEED_CTR_Decrypt( IN BYTE *pbszUserKey, IN BYTE *pbszIV, IN BYTE *pbszCipherText, IN int nCipherTextLen, OUT BYTE *pbszPlainText )
- int SEED_CTR_init( OUT KISA_SEED_INFO *pInfo, IN KISA_ENC_DEC enc, IN BYTE *pszUserKey, IN BYTE *pbszCounter )
- int SEED_CTR_Process( OUT KISA_SEED_INFO *pInfo, IN DWORD *in, IN int inLen, OUT DWORD *out, OUT int *outLen )
- int SEED_CTR_Close( OUT KISA_SEED_INFO *pInfo, IN DWORD *out, IN int *outLen )
- SEED-CCM
- int SEED_CCM_Encryption(unsigned char *ct, unsigned int *ctLen, unsigned char *pt, unsigned int ptLen, unsigned int macLen, unsigned char *nonce, unsigned int nonceLen, unsigned char *aad, unsigned int aadLen, unsigned char *mKey)
- int SEED_CCM_Decryption(unsigned char *pt, unsigned int *ptLen, unsigned char *ct, unsigned int ctLen, unsigned int macLen, unsigned char *nonce, unsigned int nonceLen, unsigned char *aad, unsigned int aadLen, unsigned char *mKey)
- SEED-GCM
- int SEED_GCM_Encryption(unsigned char *ct, unsigned int *ctLen, unsigned char *pt, unsigned int ptLen, unsigned int macLen, unsigned char *nonce, unsig
- int SEED_GCM_Decryption(unsigned char *pt, unsigned int *ptLen, unsigned char *ct, unsigned int ctLen, unsigned int macLen, unsigned char *nonce, unsigned int nonceLen, unsigned char *aad, unsigned int aadLen, unsigned char *mKey)
- SEED-CMAC
- int SEED_Generate_CMAC(unsigned char *pMAC, int macLen, unsigned char *pIn, int inLen, unsigned char *mKey)
- int SEED_Verify_CMAC(unsigned char *pMAC, int macLen, unsigned char *pIn, int inLen, unsigned char *mKey)
자바[편집]
- SEED-ECB
- public static byte[] SEED_ECB_Encrypt( byte[] pbszUserKey, byte[] pbData, int offset, int length ); : SEED-ECB 알고리즘 암호화 함수이다. pbszUserKey는 사용자가 지정하는 16바이트 입력 키고, pbData는 사용자 입력 평문이다. offset은 사용자 입력 길이 시작 오프셋을, length는 사용자 입력 길이를 의미하는 매개변수이다. 사용자 입력에 대한 암호문 출력 바이트를 반환한다. 고려해야 할 점은 pbszUserKey의 크기는 반드시 16바이트여야만 한다.
- public static byte[] SEED_ECB_Decrypt( byte[] pbszUserKey, byte[] pbData, int offset, int length ); : SEED-ECB 알고리즘 복호화 함수이다. 매개변수 pbszUserKey는 사용자가 지정하는 16바이트 입력 키고, pbData는 사용자 입력 암호문이다. offset은 사용자 입력 길이 시작 오프셋이며, length는 사용자 입력 길이를 의미하는 매개변수이다. 사용자 입력에 대한 평문 출력 바이트를 반환하는 함수로, 위와 마찬가지로 pbszUserKey의 크기는 반드시 16바이트이어야 한다.
- SEED-CBC
- public static byte[] SEED_CBC_Encrypt( byte[] pbszUserKey, byte[] pbszIV, byte[] message, int message_offset, int message_length ) : SEED-CBC 알고리즘 암호화 함수이다. 매개변수 pbszUserKey는 사용자가 지정하는 16바이트 입력 키이고, pbszIV는 사용자가 지정하는 16바이트 초기화 벡터이다. message는 사용자 입력 평문을 가리키며, message_offset은 사용자 입력 길이 시작 오프셋을, message_length은 사용자 입력 길이를 의미하는 매개변수이다. 사용자 입력에 대한 암호문 출력 바이트를 반환하는 함수이며, pbszUserKey와 pbszIV의 크기는 각각 16바이트이어야 한다.
- public static byte[] SEED_CBC_Decrypt( byte[] pbszUserKey, byte[] pbszIV, byte[] message, int message_offset, int message_length ) : SEED-CBC 알고리즘 복호화 함수이다. pbszUserKey는 사용자가 지정하는 16바이트 입력 키를, pbszIV 는 사용자가 지정하는 16바이트 초기화 벡터를 의미한다. message는 사용자 입력 평문을, message_offset은 사용자 입력 길이 시작 오프셋을, message_length은 사용자 입력 길이를 가리키는 매개변수이다. 위와 같이 사용자 입력에 대한 평문 출력 바이트를 반환하는 함수로, pbszUserKey와 pbszIV의 크기는 각각 16바이트이어야 한다.
- public static int SEED_CBC_init( KISA_SEED_INFO pInfo, KISA_ENC_DEC enc, byte[] pbszUserKey, byte[] pbszIV ) : SEED-CBC 알고리즘 초기화 함수이다. pInfo는 SEED CBC 알고리즘 운영을 위한 클래스를 지정하고, enc는 알고리즘 암호화 및 복호화 모드를 지정하는 매개변수이다. pbszUserKey는 사용자가 지정하는 16바이트 입력 키이고, pbszIV는 사용자가 지정하는 16바이트 초기화 벡터이다. 반환값으로 0과 1을 가지며, 1을 반환했다면 초기화에 성공한 것이고, 0을 반환했다면 초기화에 실패했다는 뜻이다.
- public static int SEED_CBC_Process( KISA_SEED_INFO pInfo, int[] in, int inLen, int[] out, int[] outLen ): SEED-CBC 알고리즘 다중 블록 암호화 함수이다. pInfo는 SEED CBC 알고리즘 운영을 위해 클래스를 지정하는 매개변수이며, in은 사용자 입력 평문 및 암호문을 의미한다. inLen은 사용자 입력의 길이 지정을, out은 사용자 입력에 대한 암호문 및 평문 출력 버퍼를 의미한다. outLen은 출력 버퍼에 저장된 데이터의 길이를 의미하는 매개변수이다. 0과 1을 반환하며, 1을 반환했다면 구동하는 데 성공한 것이고, 0을 반환했다면 구동에 실패한 것이다.
- public static int SEED_CBC_Close( KISA_SEED_INFO pInfo, int[] out, int out_offset, int[] outLen ) : SEED-CBC 알고리즘 운영 모드 종료 및 패딩(PKCS7) 처리 함수이다. pInfo는 SEED CBC 알고리즘 운영을 위한 클래스를 지정하고, out은 사용자 입력에 대한 최종 출력 블록이 저장되는 버퍼를 말한다. out_offset은 출력 버퍼의 시작 오프셋이며, outLen은 출력 버퍼에 저장된 데이터의 길이를 가리킨다. 반환값으로는 0과 1을 가지는데, 1인 경우에는 패딩에 성공한 것이고, 0인 경우에는 패딩에 실패했다는 뜻이다.
- SEED-CTR
- public static byte[] SEED_CTR_Encrypt( byte[] pbszUserKey, byte[] pbszCTR, byte[] message, int message_offset, int message_length )
- public static byte[] SEED_CTR_Decrypt( byte[] pbszUserKey, byte[] pbszCTR, byte[] message, int message_offset, int message_length )
- public static int SEED_CTR_init( KISA_SEED_INFO pInfo, KISA_ENC_DEC enc, byte[] pszUserKey, byte[] pbszCTR )
- public static int SEED_CTR_Process( KISA_SEED_INFO pInfo, int[] in, int inLen, int[] out, int[] outLen )
- public static int SEED_CTR_Close( KISA_SEED_INFO pInfo, int[] out, int out_offset, int[] outLen )
- SEED-CCM
- public int SEED_CCM_Encryption(byte[] ct, byte[] pt, int ptLen, int macLen, byte[] nonce, int nonceLen, byte[] aad, int aadLen, byte[] mKey)
- public int SEED_CCM_Decryption(byte[] pt, byte[] ct, int ctLen, int macLen, byte[] nonce, int nonceLen, byte[] aad, int aadLen, byte[] mKey)
- SEED-GCM
- public int SEED_GCM_Encryption(byte[] ct, byte[] pt, int ptLen, int macLen, byte[] nonce, int nonceLen, byte[] aad, int aadLen, byte[] mKey)
- public int SEED_GCM_Decryption(byte[] pt, byte[] ct, int ctLen, int macLen, byte[] nonce, int nonceLen, byte[] aad, int aadLen, byte[] mKey)
- SEED-CMAC
- public int SEED_Generate_CMAC(byte[] pMAC, int macLen, byte[] pIn, int inLen, byte[] mKey)
- public int SEED_Verify_CMAC(byte[] pMAC, int macLen, byte[] pIn, int inLen, byte[] mKey)[3]
그 외의 알고리즘[편집]
국내외 암호화 알고리즘(2017년 기준) 분류 미국(NIST) 일본(CRYPTREC) 유럽(ECRYPT) 국내 대칭키 암호 알고리즘 AES-128/192/256 3TDEA AES-128/192/256 3TDEA Camellia-128/192/256 MISTY1 AES-128/192/256 Blowfish KASUMI 3TDEA SEED, HIGHT, ARIA-128/192/256 공개키 암호 알고리즘(메시지 암/복호화) RSA(사용 권고하는 키 길이 확인 필요) RSAES-OAEP RSAES-PKCS1 RSAES-OAEP RSAES-PKCS1 RSAES-OAEP 일방향 암호 알고리즘 SHA-224/256/384/512 SHA-256/384/512 SHA-224/256/384/512 Whirlpool SHA-224/256/384/512
국내[편집]
- ARIA(Academy Research Institute Agency) : 전자정부 구현 등으로 다양한 환경에 적합한 암호화 알고리즘의 필요성이 대두됐고, 이에 따라 국가보안기술연구소 주도로 학계와 국가 정보원 등의 암호기술 전문가들이 힘을 모아서 개발한 국가 암호화 알고리즘이다. ISPN 구조의 128비트 블록 암호이며, 128비트, 192비트, 256비트 세 가지 키를 제공한다. 이들 각각은 키 길이에 따라 ARIA-128, ARIA-192, IRIA-256으로 구분한다. ARIA의 입출력 크기와 사용 가능한 키 크기는 미국 표준 블록 암호인 AES와 동일하다.
- HIGHT(HIGH security and light weightT) : RFID, USN 등과 같이 저전력과 저경량을 요구하는 컴퓨팅 환경에서 기밀성을 제공하기 위해 개발된 64비트 블록 암호이다.
- LEA(Lightweight Encryption Algorithm) : 128비트 경량 고속 블록 암호 알고리즘이다. AES보다 1.5에서 2배는 빠르다. 다양한 정보보안 서비스에서 다양한 데이터를 빠르게 처리할 수 있고, 스마트폰의 보안과 사물 인터넷 등의 저전력 암호화에도 널리 사용할 수 있다.
국외[편집]
- IDEA(International Data Encrption Algorithm)
- DES를 대체하기 위하여 스위스의 한 연방기술 기관에서 개발한 알고리즘이다. 128비트 키, 64비트 블록 암호로 파이스텔 구조를 변형했다. 파이스텔과 SPN의 중간 형태이다. 8라운드를 걸쳣 데이터를 변환하며, 마지막에 한 번 더 키를 적용해 64비트 암호문을 생성하기 때문에, 보통 8.5라운드라고도 부른다. IDEA는 DES와는 달리 S-box를 사용하지 않고 대수적 구조가 서로 다른 연산을 번갈아 사용해서 암호학적인 강도를 높였다. PGP의 데이터 암호 알고리즘으로 채택되어 사용되고 있으며, DES보다 2배 정도 빠르고 무차별 공격에 더욱 효율적으로 대응한다.
- RC5(Ron's Code 5) : 1994년, 미국의 RSA 연구소의 라이베스트가 개발했다. 비교적 간단한 연산으로 빠른 암호화와 복호화 기능을 제공할 수 있는 알고리즘으로, 모든 하드웨어에 적합한 편이다. 입출력과 키, 라운드 수가 가변인 블록 알고리즘이며, 32/64/128비트의 블록을 갖고 있고, 속도는 DES의 약 10배이다. 간단한 알고리즘과 빠른 속도가 특징이다.
- DES : 미국 연방정부(NIST)에서 1977년 표준으로 공표, 16라운드의 알고리즘이며, 블록은 64비트 크기이다.
- AES : 미국 연방정부에서 표준으로 공표, 128/192/256 비트키
- FEAL : 소프트웨어 구현에 적합하다. 64/128비트 블록크기[4][5]
각주[편집]
- ↑ 한국인터넷진흥원, 〈[SEED 128 알고리즘 상세 명세서]〉, 《한국인터넷진흥원》, 2009-07
- ↑ 2.0 2.1 한국인터넷진흥원 공식홈페이지 SEED - https://seed.kisa.or.kr/kisa/algorithm/EgovSeedInfo.do
- ↑ 3.0 3.1 3.2 관리자1, 〈암호알고리즘 소스코드〉, 《한국인터넷진흥원》, 2019-01-31
- ↑ 와이준 Nye, 〈(암호학) 기타 대칭키 암호 알고리즘 - IDEA, RC5, SEED, ARIA, HIGHT, LEA〉, 《티스토리》, 2019-11-19
- ↑ ojava, 〈KISA 권고 암/복호화 방식:SEED 128, SEED 256〉, 《티스토리》, 2017-05-15
참고자료[편집]
- SEED 위키백과 - https://ko.wikipedia.org/wiki/SEED
- SEED 나무위키 - https://namu.wiki/w/SEED
- 한국인터넷진흥원 공식홈페이지 SEED - https://seed.kisa.or.kr/kisa/algorithm/EgovSeedInfo.do
- 한국인터넷진흥원, 〈[SEED 128 알고리즘 상세 명세서]〉, 《한국인터넷진흥원》, 2009-07
- ojava, 〈KISA 권고 암/복호화 방식:SEED 128, SEED 256〉, 《티스토리》, 2017-05-15
- 관리자1, 〈암호알고리즘 소스코드〉, 《한국인터넷진흥원》, 2019-01-31
- 와이준 Nye, 〈(암호학) 기타 대칭키 암호 알고리즘 - IDEA, RC5, SEED, ARIA, HIGHT, LEA〉, 《티스토리》, 2019-11-19
같이 보기[편집]