PHP로 구현한 SEED128 + CBC + PKCS5 암호화

SEED 암호알고리즘
SEED를 제공하는 인터넷진흥원 사이트 스크린샷

 

Prologue

회사에서 미션이 하나 떨어졌습니다. 한국인터넷진흥원에서 순수 국내기술로 개발된 SEED128을 PHP로 구현하는 것 입니다.
참고로 한국인터넷진흥원에서 JAVA나 C언어로는 SEED소스를 제공하고 있습니다. 심지어 안드로이드와 Objective-C도 제공하는데 PHP만 없습니다.
SEED에 관련된 내용은 해당 사이트에서 참고하시기 바라오며, 현재 표준으로 채택되어져 각종 금융기관에서 널리 사용되고 있다는 것만 알고계시면 될 것 같습니다.

SEED 암호화 기술은 블록 암호 알고리즘을 채택하고 있어 통신하기 위한 곳 모두 동일한 Key를 가지고 있어야 암호화와 복호화가 가능합니다.
저 역시 금융기관쪽과 중요한 데이터를 통신을 하기 위해서 사용하는 것 이며 해당 금융기관쪽은 자바로 이미 구현되어 있어 동일한 Key를 가지고 저희쪽 PHP로 암/복호화가 가능해야 합니다.
사실 말이 PHP로 구현하는 것이지 Native 언어는 명확한 기준으로 변수타입들이 정해져 있기라도 하지만 웹 전용으로 유연하게 만들어진 PHP에서 지원할리 없기때문에 무수한 삽질이 예상되었습니다.

우선 검색하기 시작했습니다. 다행히도 SEED자체에 대한 프로세스는 PHP로 구현해놓으신 분이 계셨습니다. 아래에서 class.seed.php를 다운로드 받으시면 됩니다.
다시한번 이자리를 빌어 정말 감사드립니다.

출처: http://docs.cena.co.kr/textyle/15770

하지만 위의 소스는 순수하게 SEED만 구현해 놔서 제가 원하는 것을 구현하기에는 부족했으며, 기존 class.seed.php 클래스는 운영체제가 64bit인 경우 Integer의 Max값이 커지다보니 라운드키의 정수값을 오버플로우 시키지 못하는 증상으로 인해 값을 제대로 출력하지 못하는 문제가 있어 이 부분은 별도로 해결했습니다.

[box type=”info”]자바는 플랫폼에 관계없이 32비트 고정이지만, PHP는 플랫폼에 따라 32비트면 정수의 최대값이 2147483647이고, 64비트면 9223372036854775807로 자동으로 할당됩니다.[/box]

암호화를 운용하기 위해서 저의 경우에는 CBC와 PKCS5 방식으로 구현을 해야하며 통상적으로 검색하면 나오는 IV의 값도 PHP에서 사용하는 랜덤 스트링 형태가 아닌 자바와 동일하게 바이트 배열로 정해진 값을 만들어서 써야 하기 때문에 본젹적인 개발과 검색에 들어가기 시작했습니다. 말 자체를 이해 못하시는 분들을 위해 용어에 대한 정의들 부터 살펴보겠습니다.

 

암호 블록 체인 방식 (CBC)

그림을 보면 더 이해가 잘 되야 하는데~ 저는 이런 그림을 별로 좋아하지 않아서 이해가 잘 되지 않았습니다.
간단하게 설명하면 이전 블록의 암호문을 현재 평문 블록을 암호화할 때 사용하면서 운용하는 모드입니다. 따라서 같은 평문들도 서로 다른 암호문 블록으로 순차적으로 암호화가 이루어지게 됩니다. 하지만 처음 나오는 평문을 암호화할 암호문이 없기 때문에 보통 랜덤으로 만들게 되며 이를 IV(초기화 벡터)라고 합니다.
평문의 첫번째 블록이 IV와 XOR을 수행하고 나서 암호화를 수행하게 되며 다음은 그 암호화된 블록이 평문의 다음블록을 XOR하는 식으로 평문 블록을 마칠때까지 반복하는 구조입니다. 이게 저도 수도 없이 봤지만 쉽게 이해가 되지 않더군요! 그래도 이해하고 넘어가셔야 합니다. 아래는 위키피디아에서 발췌한 이미지를 첨부하였으며 이해가 안되시는 내용은 구글링을 통해 확인하시기 바랍니다.

Cbc encryption.png
CBC 운영모드에서의 암호화
Cbc decryption.png
CBC 운영모드에서의 복호화

Continue reading PHP로 구현한 SEED128 + CBC + PKCS5 암호화