openssl 은 ssl 의 공개버젼으로써, 주로 네트웍상에서 암호화 통신을 가능하게 하기 위한 목적으로 사용된다. 여기에서는 openssl 에서 제공하는 crypto 라이브러리를 이용해서 데이타를 암호화 하는 방법에 대해서 알아보도록 하겠다.
1절. 소개
2절. OpenSSL
2.1절. SSL 에 대해서
3절. Openssl 을 통한 암호화
3.1절. blowfish 알고리즘을 이용한 데이타 암호화
3.2절. 데모프로그램 설계문서
3.2.1절. 프로그램 기능설명
3.2.2절. Key 생성하기
3.3절. 코딩
3.3.1절. 동적라이브러리 제작을 위한 API 인터페이스
3.3.2절. fcrypt.c
3.3.3절. blowfish.c
3.4절. 테스트
4절. 결론
--------------------------------------------------------------------------------
1절. 소개
최근에는 단지 방화벽, IDS 로 침입차단/침입탐지 정도의 수준만이 아닌 중요한 데이타의 암호화까지를 이용해서 보안수준을 높이고자 노력하고 있다. 이글은 데이타와 암호화와 관련된 많은 방법중 쉽게 사용할수 있을만한 방법을 제안한다.
--------------------------------------------------------------------------------
2절. OpenSSL
우리는 데이타 암호화를 위해서 가장 널리사용된다고 믿어지고 있는 SSL의 Open 버젼인 OpenSSL 라이브러리를 이용할것이다. 이 라이브러리는 Apache, PGP, SMTP 서버, POP 서버 등 데이타를 교환하는 많은 인터넷 서비스 프로그램에서 사용되어지고 있으며, 로컬데이타(파일) 암호화를 위한 도구로도 널리 사용되고 있다.
OpenSSL 을 사용하는 가장유명한 어플리케이션은 SSH 와 https 를 지원하는 웹브라우저와 웹서버가 될것이다(Opera, Mozilla, explore, lynx 등 대부분의 웹브라우저와 Apache, IIS 웹서버).
이번장에서는 SSL 에 대한 기본적인 개념과 사용방법에 대해서 알아볼것이다.
--------------------------------------------------------------------------------
2.1절. SSL 에 대해서
SSL 은 Secure Sockets Layer 의 줄임말이며, 네트웍 소켓의 데이타 입출력을 암호화 하기 위한 (프로그램)계층(Layer) 이다. SSL 은 넷스케이프 브라우저로 유명한 Netscape 회사에서 만들었으며 산업표준으로 사용되어 지고 있다.
SSL 을 만든이유는 기존의 TCP/IP 가 데이타암호화를 위한 어떠한 방법도 제공해주지 않기 때문으로, 네트웍내에서의 메시지 전송을 안전하게 하기 위한 용도로 만들어졌다. SSL TCP/IP 가 제공하지 않는 데이타 암호화를 지원하기 위해서 다음과 같이 Socket Layer 와 NetWork 계층사에 놓이며, Socket Layer 를 통해 전달된 데이타를 암호화 해서 NetWork 계층에 넘겨주며, Network 계층을 통해서 전달된 암호화 데이타를 복호화 해서 Socket Layer 로 전달해주는 구조를 가진다.
SSL 은 전자서명에 널리사용되는 암호화 알고리즘인 RSA 를 주 알고리즘으로 사용한다. RSA 는 암호화와 복호화를 위해서 개인키 와 공개키 를 사용한다. 간단히 말해서 암호화에 사용하는 키와 복호화에 사용되는 키가 분리되어 있는 알고리즘이다.
개인키는 말그대로 개인이 유일하게 가지고 있는키이며 이 키를 이용해서 데이타를 암호화 시킨다. 암호화된 데이타를 복호화 하기 위해서는 공개키를 사용해야 하는데, 이 공개키는 모두에게(데이타를 보내고자하는) 공개된다.
데이타를 수신 하는 사람에게 공개키를 보낸다.
보내고자 하는데이타를 개인키를 이용해서 암호화 한다.
암호화된 데이타를 수신자에게 전송한다. 암호화되어 있음으로 다른 사람은 볼수 없다.
데이타 수신자는 공개키를 이용해서 데이타를 복호화 한다.
메일의 암호화를 위해서 PGP 를 사용해본적이 있다면, 위의 과정을 쉽게 이해할수 있을것이다. PGP 를 사용할경우 데이타 송신자는 자신 데이타 암호화를 위한 개인키와 복호화를 위한 공개키를 생성하고 만들어진 공개키를 요러가지 경로를 통해서 데이타 수신자에게 전달한다(디스크, 혹은 메일, 웹등으로). 그후 데이타를 보낼때는 개인키로 데이타를 암호화 해서 보내고, 받은 측은 공개키를 이용해서 데이타를 복호화 한다.
이상 간단하게 SSL 에 대해서 알아보았는데, SSL 은 매우 방대하며 복잡한 내용임으로 여기에서 모두 다룰수는 없다. 여기에 관한 내용은 openssl.org를 참고하기 바란다.
--------------------------------------------------------------------------------
3절. Openssl 을 통한 암호화
3.1절. blowfish 알고리즘을 이용한 데이타 암호화
이 문서에서는 RSA 암호화 알고리즘대신 blowfish 알고리즘을 사용해서 데이타를 암/복호화 할것이다. Blowfish 는 데이타 암호화및 복호화를 위해서 동일한 키를 사용하는 대칭 알고리즘(symmetric algorithm)을 사용하고 있다.
암/복호화를 위한 다른키를 사용하는 RSA 알고리즘에 비해서 사용하기가 간단하고, 더 빠른 수행능력을 보여준다는 장점을 가진다.
--------------------------------------------------------------------------------
3.2절. 데모프로그램 설계문서
우리는 파일을 암호화해서 저장하는 어플리케이션을 제작할 것이다. 코딩에 들어가기 전에 간단단하게 기능과 원리를 정의하는 설계도(설계도라고 하기엔 부족하지만)를 만들어보도록 하겠다.
--------------------------------------------------------------------------------
3.2.1절. 프로그램 기능설명
프로그램은 key 를 생성하고 생성된 key 를 이용해서 프로그램 인자로 주어지는 파일을 암호화 하게 된다. 암호화된 파일을 복호화 하기 위해서는 key 가 필요하게 되는데, 이 key 는 별도의 파일로 저장하게 된다. 그럼으로 암호화된 파일을 복호화 하기 위해서는 반드시 key 파일이 존재해야만 한다.
암호화된 파일의 가장 앞부분에는 암호화된 파일의 정보를 알려주는 헤더가 들어갈것이다. 이것은 이 파일이 우리가 만든 프로그램을 통해서 암호화 되었다는 정보와 함께 버젼정보, 사용한 암호화 알고리즘 종류, key 를 제작한사람 등에 관한 정보가 들어간다.
파일에 이처럼 다양한 부가정보를 추가하는 이유는 확장이 필요한 경우가 생길수 있기 때문이다. 예를들어 지금은 단지 blowfish 알고리즘만을 사용하고 있지만 다른 암호화알고리즘을 지원하도록 추가할수도 있기 때문이다.
또한 어플리케이션은 동적라이브러리를 지원하도록 만들어진다. 이유는 다른 암호화 알고리즘이 추가되었을경우 코드를 다시 컴파일하는 불편함을 줄이기 위해서이다.
--------------------------------------------------------------------------------
3.2.2절. Key 생성하기
fcrypt 에서는 암/복호화를 위한 키의 크기를 128bit 로 하겠다. 만들어진 키를 이용해서 암호화를 한후 별도의 파일로 저장될것이다. 이유는 나중에 복호화 할때도 동일한 키를 사용해야 하기 때문이다. 복호화 할때는 존재하고 있는 키 파일에서 파일에 대한 키를 얻어오고 이 데이타를 이용해서 복호화 할것이다.
키의 생성은 커널난수 생성기인 /dev/random 문자장치파일을 이용할것이다.
--------------------------------------------------------------------------------
3.3절. 코딩
프로그램의 이름은 fcrypt 로 할것이다. 코드는 크개 2개의 부분으로 이루어지는데, 하나는 fcrypt.c 로써 실제 사용자에게 제공되는 프로그램이며, 다른 하나는 bolwfish.c 로써 암호화기능을 제공하는 프로그램이다.
blowfish.c 는 main 함수를 제공하지 않으며, 동적라이브러리형태로 제작될 것이며, fcrypt 에서는 이 라이브러리를 적재해서 파일을 암호화 하게 될것이다.
--------------------------------------------------------------------------------
3.3.1절. 동적라이브러리 제작을 위한 API 인터페이스
동적라이브러리 형태로 만드는 이유는 사용자이 필요에 따라서 다양한 암호화 알고리즘을 적용시킬수 있도록 유연성을 높이기 위함이다. 일종의 Plug in 형태로 작동하게 된다.
이처럼 본체프로그램과 기능추가를 위한 Plug in 이 따로 분리 되어서 제작될경우에 Plug in 의 제작을 위한 공통 인터페이스를 제공하게 된다. 그래야만 본체프로그램 코드의 수정없이 단지 plug in 라이브러리만 추가함으로써, 기능을 확장시킬수 있기 때문이며, 그러기 위해서는 공통된 인터페이스에 따라서 Plug in 라이브러리를 제작해야 한다.
동적라이브러리는 반드시 아래와 같은 4가지의 인터페이스를 (정확히 말하자면 함수선언)을 이용해서 프로그래밍 되어야한다. 본체 프로그램은 단지 이 4가지 함수들만을 호출해서 모든 작업을 할수 있도록 라이브러리 제작자는 신경을 써야한다.
crypt_open()과 crypt_close() 는 라이브러리 개발자의 편의를 위해서 제공되는 인터페이스다. 예를들자면 특정 암호화알고리즘을 적용해서 라이브러리를 만들경우 여러가지 초기화작업이 필요한 경우가 있을것이다. 메모리 할당, 초기화, 메모리 해제 등과 같은 작업이 대표적일 것이다. crypt_open() 은 이러한 초기화 작업을 위해서 사용되며, crypt_close() 는 메모리 해제와 같은 작업을 위해서 사용된다.
mycrypt() 는 암호화를 위한 함수이다. filename 은 암호화 하고자 하는 파일이름이며 header는 헤더정보를 입력받기 위해서 사용되는 아규먼트이다.
mydecrypt() 는 복호화를 위한 함수이다. filename 은 복호화 하고자 하는 파일이름 이며, header 는 헤더정보, keyfile 은 복호화 하기 위해서 사용하는 키가 저장된 파일의 이름이다. header 이 인자로 넘겨지는 이유는 복호화 하고자 하는 파일의 버젼체크등을 위한 목적이다. 암호파일의 버젼과 본체프로그램의 버젼이 전혀 틀릴경우 (메이져 버젼에서 차이가 생길경우) 복호화가 제대로 되지 않을수 있음으로 이를 체크하기 위한 목적이다.
그럼으로 main() 함수를 포함하는 본체 프로그램은 단지 다음과 같이 함수를 호출함으로써 모든 작업을 마치게 되며, 암호/복호화 알고리즘 내부에서 어떤 일을 하는지 신경쓰지 않아도 된다. 일종의 캡슐화라고 볼수 있다.
--------------------------------------------------------------------------------
3.3.2절. fcrypt.c
이 코드는 아규먼트로 암/복호화 할 파일의 이름을 받아들인다. 암호화 할것인지 복호화 할것인지는 역시 아규먼트를 통해서 지정할수 있도록 할것이다. 역시 아규먼트를 통하여서 암호화방법을 지정할수 있으며, 아규먼트로 지정된 암호화 방법에 따라서 어플리케이션은 적당한 라이브러리를 동적으로 적재해서 암호화 혹은 복호화 하게 된다.
이 프로그램은 암호화종류에 따른 라이브러리를 동적으로 적재하기 위해서 설정파일을 가지며, 아규먼트를 통해서 선택된 암호화방법에 적당한 라이브러리를 찾기 위한 목적으로 사용된다. 설정파일은 다음과 같이 구성된다. 설정파일의 이름은 plugin.cfg 로 하겠다.
blowfish,libblowfish,blowfish 알고리즘
mycrypt,libmycrypt,사용자 정의 암호화 알고리즘
null,libnull,null function 알고리즘
3개의 필드를 가진다. 첫번째 필드에는 암호화이름 두번째 필드는 불러들일 라이브러리 이름, 세번째 필드는 간단한 설명이다.
암호화할때는 파일의 가장앞에 암호화된 파일의 정보구조체를 집어 넣을것이다. 이 구조체는 다음과 같다.
다음은 실제코드이며, 설명은 주석으로 대신하도록 한다.
예제 : fcrypt.c
fcrypt.c 는 다음과 같이 컴파일하면 된다. [root@localhost crypt2]# gcc -o fcrypt fcrypt.c -ldl -lcrypto
--------------------------------------------------------------------------------
3.3.3절. blowfish.c
이것은 fcrypt 프로그램에서 동적으로 적재할 플러그인 프로그램으로 blowfish 알고리즘을 통해서 주어진 파일을 암호화 하고 복호화 한다.
blowfish 는 앞에서 말했듯이 암호화에 사용된 key 를 가지고 복호화를 하게 된다. 당연히 이러한 key 데이타를 파일로 저장하고 있어야 할것이다.
그럼으로 blowfish 는 파일을 암호화 하게 될경우 암호화된 파일과 암호화에 사용된 key 를 저장하는 파일 이렇게 2개의 파일을 생성한다. 암호화된 파일은 원본파일뒤에 ".cry" 를 붙이고, key 파일은 원본파일 뒤에 ".key"를 붙이도록 해서 생성하도록 할것이다.
key 사이즈는 128 bit 로 할것이다. 이 blowfish 는 openssl 의 crypto 라이브러리에서 제공한다. 그리고 랜덤한 key 를 생성하기 위해서 /dev/random 커널 난수 생성기를 이용할것이다. 커널 난수 생성기에 대해서는 random 값 얻어오기를 참고하기 바란다.
crypto 에서 제공하는 blofish 암호화 알고리즘에는 key 외에도 initalization vector 가 필요하다. 이것의 크기는 64bit 로 할것이며, 마찬가지로 /dev/random 을 이용해서 랜덤하게 생걱할것이다. 고로 실제 key 파일에는 key 값과 initalization vector 값이 저장될 것이다.
그리고 Cipher Block Chaining(CBC) 모드 상태에서 암/복호화를 하게 될것이다.
예제 : blowfish.c
blowfish.c 는 공유라이브러리 형태로 만들어줘야 한다. 다음과 같이 공유라이브러리 형태로 만들어주자. [root@localhost crypt2]# gcc -c -fPIC blowfish.c
[root@localhost crypt2]# gcc -shared -W1,-soname,libblowfish.so.1 -o libblowfish.so.1.0.1 blowfish.o
이렇게 하면 libblowfish.so.1.0.1 이라는 라이브러 파일이 만들어 진다. 이 파일은 plugin 디렉토리를 만들어서 복사하고 다음과 같이 심볼릭 링크를 걸어주도록 하자.
[root@localhost crypt2]# mkdir plugin
[root@localhost crypt2]# cp libblowfish.so.1.0.1 plugin/
[root@localhost crypt2]# cd plugin
[root@localhost plugin]# ln -s libblowfish.so.1.0.1 libblowfish.so
--------------------------------------------------------------------------------
3.4절. 테스트
테스트를 하기 위해서는 plugin.cfg 파일이 있어야 하며, plugin 디렉토리 밑에 해당 암호화 알고리즘을 지원하는 라이브러리가 존재하고 있어야 한다. 다음은 필자의 plugin.cfg 의 파일이다.
blowfish,libblowfish.so,blowfish 알고리즘
null,libnull.so,null function 알고리즘
blowfish 는 무엇인지 알테고, null 은 필자가 동적라이브러리 테스트용으로 만든 것으로 말그대로 null 이다. 즉 아무런 암호화 과정없이 그대로 원본내용을 그대로해서 암호화파일을 만든다. 각자 만들어 보기 바란다.
plugin 밑에는 다음과 같은 파일들이 있다.
[root@localhost plugin]# ls
libblowfish.so libblowfish.so.1.0.1 libnull.so libnull.so.1.0.1
이제 테스트를 해보자, 테스트 결과의 확인을 쉽게 하기 위해서 text 파일을 테스트에 사용하도록 하자. 필자는 fcrypt.c 를 암호화/복화화 테스트에 사용하도록 했다.
다음은 암호화 테스트로 fcrypt.c 를 blowfish 알고리즘을 사용한 테스트 결과이다.
[root@localhost crypt2]# ./fcrypt -c fcrypt.c -t blowfish
ok encrypt
실행결과 암호화된 파일인 fcrypt.c.cry 와 key 가 저장된 fcrypt.c.key 가 생성되었음을 확인할수 있을것이다.
다음은 암호화된 파일의 정보를 얻어오는 테스트이다.
[root@localhost crypt2]# ./fcrypt -i fcrypt.c.cry
Version : 1.0
crypttype : blowfish
다음은 fcrypt 가 현재 지원하는 plug in 알고리즘의 목록을 출력한 것이다.
[root@localhost crypt2]# ./fcrypt -l
blowfish libblowfish.so blowfish 알고리즘
null libnull.so null function 알고리즘
다음은 복호화 시킨 결과이다.
[root@localhost crypt2]# ./fcrypt -d fcrypt.c.cry -t blowfish -k fcrypt.c.key
--------------------------------------------------------------------------------
4절. 결론
이상 openssl 을 이용한 암호화방법에 대해서 알아보았다. 위의 예제 프로그램들은 수정해야할 여지가 많을것이다.
여기에서는 단지 파일만을 예로 들었지만, 네트웍 프로그래밍등에도 충분히 응용이 가능할것이다.
출처 : http://joinc.co.kr/modules.php?name=new ··· 3Dnested
1절. 소개
2절. OpenSSL
2.1절. SSL 에 대해서
3절. Openssl 을 통한 암호화
3.1절. blowfish 알고리즘을 이용한 데이타 암호화
3.2절. 데모프로그램 설계문서
3.2.1절. 프로그램 기능설명
3.2.2절. Key 생성하기
3.3절. 코딩
3.3.1절. 동적라이브러리 제작을 위한 API 인터페이스
3.3.2절. fcrypt.c
3.3.3절. blowfish.c
3.4절. 테스트
4절. 결론
--------------------------------------------------------------------------------
1절. 소개
최근에는 단지 방화벽, IDS 로 침입차단/침입탐지 정도의 수준만이 아닌 중요한 데이타의 암호화까지를 이용해서 보안수준을 높이고자 노력하고 있다. 이글은 데이타와 암호화와 관련된 많은 방법중 쉽게 사용할수 있을만한 방법을 제안한다.
--------------------------------------------------------------------------------
2절. OpenSSL
우리는 데이타 암호화를 위해서 가장 널리사용된다고 믿어지고 있는 SSL의 Open 버젼인 OpenSSL 라이브러리를 이용할것이다. 이 라이브러리는 Apache, PGP, SMTP 서버, POP 서버 등 데이타를 교환하는 많은 인터넷 서비스 프로그램에서 사용되어지고 있으며, 로컬데이타(파일) 암호화를 위한 도구로도 널리 사용되고 있다.
OpenSSL 을 사용하는 가장유명한 어플리케이션은 SSH 와 https 를 지원하는 웹브라우저와 웹서버가 될것이다(Opera, Mozilla, explore, lynx 등 대부분의 웹브라우저와 Apache, IIS 웹서버).
이번장에서는 SSL 에 대한 기본적인 개념과 사용방법에 대해서 알아볼것이다.
--------------------------------------------------------------------------------
2.1절. SSL 에 대해서
SSL 은 Secure Sockets Layer 의 줄임말이며, 네트웍 소켓의 데이타 입출력을 암호화 하기 위한 (프로그램)계층(Layer) 이다. SSL 은 넷스케이프 브라우저로 유명한 Netscape 회사에서 만들었으며 산업표준으로 사용되어 지고 있다.
SSL 을 만든이유는 기존의 TCP/IP 가 데이타암호화를 위한 어떠한 방법도 제공해주지 않기 때문으로, 네트웍내에서의 메시지 전송을 안전하게 하기 위한 용도로 만들어졌다. SSL TCP/IP 가 제공하지 않는 데이타 암호화를 지원하기 위해서 다음과 같이 Socket Layer 와 NetWork 계층사에 놓이며, Socket Layer 를 통해 전달된 데이타를 암호화 해서 NetWork 계층에 넘겨주며, Network 계층을 통해서 전달된 암호화 데이타를 복호화 해서 Socket Layer 로 전달해주는 구조를 가진다.

그림 1. SSL 계층구조
SSL 은 전자서명에 널리사용되는 암호화 알고리즘인 RSA 를 주 알고리즘으로 사용한다. RSA 는 암호화와 복호화를 위해서 개인키 와 공개키 를 사용한다. 간단히 말해서 암호화에 사용하는 키와 복호화에 사용되는 키가 분리되어 있는 알고리즘이다.
개인키는 말그대로 개인이 유일하게 가지고 있는키이며 이 키를 이용해서 데이타를 암호화 시킨다. 암호화된 데이타를 복호화 하기 위해서는 공개키를 사용해야 하는데, 이 공개키는 모두에게(데이타를 보내고자하는) 공개된다.
데이타를 수신 하는 사람에게 공개키를 보낸다.
보내고자 하는데이타를 개인키를 이용해서 암호화 한다.
암호화된 데이타를 수신자에게 전송한다. 암호화되어 있음으로 다른 사람은 볼수 없다.
데이타 수신자는 공개키를 이용해서 데이타를 복호화 한다.
메일의 암호화를 위해서 PGP 를 사용해본적이 있다면, 위의 과정을 쉽게 이해할수 있을것이다. PGP 를 사용할경우 데이타 송신자는 자신 데이타 암호화를 위한 개인키와 복호화를 위한 공개키를 생성하고 만들어진 공개키를 요러가지 경로를 통해서 데이타 수신자에게 전달한다(디스크, 혹은 메일, 웹등으로). 그후 데이타를 보낼때는 개인키로 데이타를 암호화 해서 보내고, 받은 측은 공개키를 이용해서 데이타를 복호화 한다.
이상 간단하게 SSL 에 대해서 알아보았는데, SSL 은 매우 방대하며 복잡한 내용임으로 여기에서 모두 다룰수는 없다. 여기에 관한 내용은 openssl.org를 참고하기 바란다.
--------------------------------------------------------------------------------
3절. Openssl 을 통한 암호화
3.1절. blowfish 알고리즘을 이용한 데이타 암호화
이 문서에서는 RSA 암호화 알고리즘대신 blowfish 알고리즘을 사용해서 데이타를 암/복호화 할것이다. Blowfish 는 데이타 암호화및 복호화를 위해서 동일한 키를 사용하는 대칭 알고리즘(symmetric algorithm)을 사용하고 있다.
암/복호화를 위한 다른키를 사용하는 RSA 알고리즘에 비해서 사용하기가 간단하고, 더 빠른 수행능력을 보여준다는 장점을 가진다.
--------------------------------------------------------------------------------
3.2절. 데모프로그램 설계문서
우리는 파일을 암호화해서 저장하는 어플리케이션을 제작할 것이다. 코딩에 들어가기 전에 간단단하게 기능과 원리를 정의하는 설계도(설계도라고 하기엔 부족하지만)를 만들어보도록 하겠다.
--------------------------------------------------------------------------------
3.2.1절. 프로그램 기능설명
프로그램은 key 를 생성하고 생성된 key 를 이용해서 프로그램 인자로 주어지는 파일을 암호화 하게 된다. 암호화된 파일을 복호화 하기 위해서는 key 가 필요하게 되는데, 이 key 는 별도의 파일로 저장하게 된다. 그럼으로 암호화된 파일을 복호화 하기 위해서는 반드시 key 파일이 존재해야만 한다.
암호화된 파일의 가장 앞부분에는 암호화된 파일의 정보를 알려주는 헤더가 들어갈것이다. 이것은 이 파일이 우리가 만든 프로그램을 통해서 암호화 되었다는 정보와 함께 버젼정보, 사용한 암호화 알고리즘 종류, key 를 제작한사람 등에 관한 정보가 들어간다.
파일에 이처럼 다양한 부가정보를 추가하는 이유는 확장이 필요한 경우가 생길수 있기 때문이다. 예를들어 지금은 단지 blowfish 알고리즘만을 사용하고 있지만 다른 암호화알고리즘을 지원하도록 추가할수도 있기 때문이다.
또한 어플리케이션은 동적라이브러리를 지원하도록 만들어진다. 이유는 다른 암호화 알고리즘이 추가되었을경우 코드를 다시 컴파일하는 불편함을 줄이기 위해서이다.
--------------------------------------------------------------------------------
3.2.2절. Key 생성하기
fcrypt 에서는 암/복호화를 위한 키의 크기를 128bit 로 하겠다. 만들어진 키를 이용해서 암호화를 한후 별도의 파일로 저장될것이다. 이유는 나중에 복호화 할때도 동일한 키를 사용해야 하기 때문이다. 복호화 할때는 존재하고 있는 키 파일에서 파일에 대한 키를 얻어오고 이 데이타를 이용해서 복호화 할것이다.
키의 생성은 커널난수 생성기인 /dev/random 문자장치파일을 이용할것이다.
--------------------------------------------------------------------------------
3.3절. 코딩
프로그램의 이름은 fcrypt 로 할것이다. 코드는 크개 2개의 부분으로 이루어지는데, 하나는 fcrypt.c 로써 실제 사용자에게 제공되는 프로그램이며, 다른 하나는 bolwfish.c 로써 암호화기능을 제공하는 프로그램이다.
blowfish.c 는 main 함수를 제공하지 않으며, 동적라이브러리형태로 제작될 것이며, fcrypt 에서는 이 라이브러리를 적재해서 파일을 암호화 하게 될것이다.
--------------------------------------------------------------------------------
3.3.1절. 동적라이브러리 제작을 위한 API 인터페이스
동적라이브러리 형태로 만드는 이유는 사용자이 필요에 따라서 다양한 암호화 알고리즘을 적용시킬수 있도록 유연성을 높이기 위함이다. 일종의 Plug in 형태로 작동하게 된다.
이처럼 본체프로그램과 기능추가를 위한 Plug in 이 따로 분리 되어서 제작될경우에 Plug in 의 제작을 위한 공통 인터페이스를 제공하게 된다. 그래야만 본체프로그램 코드의 수정없이 단지 plug in 라이브러리만 추가함으로써, 기능을 확장시킬수 있기 때문이며, 그러기 위해서는 공통된 인터페이스에 따라서 Plug in 라이브러리를 제작해야 한다.
동적라이브러리는 반드시 아래와 같은 4가지의 인터페이스를 (정확히 말하자면 함수선언)을 이용해서 프로그래밍 되어야한다. 본체 프로그램은 단지 이 4가지 함수들만을 호출해서 모든 작업을 할수 있도록 라이브러리 제작자는 신경을 써야한다.
crypt_open()과 crypt_close() 는 라이브러리 개발자의 편의를 위해서 제공되는 인터페이스다. 예를들자면 특정 암호화알고리즘을 적용해서 라이브러리를 만들경우 여러가지 초기화작업이 필요한 경우가 있을것이다. 메모리 할당, 초기화, 메모리 해제 등과 같은 작업이 대표적일 것이다. crypt_open() 은 이러한 초기화 작업을 위해서 사용되며, crypt_close() 는 메모리 해제와 같은 작업을 위해서 사용된다.
mycrypt() 는 암호화를 위한 함수이다. filename 은 암호화 하고자 하는 파일이름이며 header는 헤더정보를 입력받기 위해서 사용되는 아규먼트이다.
mydecrypt() 는 복호화를 위한 함수이다. filename 은 복호화 하고자 하는 파일이름 이며, header 는 헤더정보, keyfile 은 복호화 하기 위해서 사용하는 키가 저장된 파일의 이름이다. header 이 인자로 넘겨지는 이유는 복호화 하고자 하는 파일의 버젼체크등을 위한 목적이다. 암호파일의 버젼과 본체프로그램의 버젼이 전혀 틀릴경우 (메이져 버젼에서 차이가 생길경우) 복호화가 제대로 되지 않을수 있음으로 이를 체크하기 위한 목적이다.
그럼으로 main() 함수를 포함하는 본체 프로그램은 단지 다음과 같이 함수를 호출함으로써 모든 작업을 마치게 되며, 암호/복호화 알고리즘 내부에서 어떤 일을 하는지 신경쓰지 않아도 된다. 일종의 캡슐화라고 볼수 있다.
--------------------------------------------------------------------------------
3.3.2절. fcrypt.c
이 코드는 아규먼트로 암/복호화 할 파일의 이름을 받아들인다. 암호화 할것인지 복호화 할것인지는 역시 아규먼트를 통해서 지정할수 있도록 할것이다. 역시 아규먼트를 통하여서 암호화방법을 지정할수 있으며, 아규먼트로 지정된 암호화 방법에 따라서 어플리케이션은 적당한 라이브러리를 동적으로 적재해서 암호화 혹은 복호화 하게 된다.
이 프로그램은 암호화종류에 따른 라이브러리를 동적으로 적재하기 위해서 설정파일을 가지며, 아규먼트를 통해서 선택된 암호화방법에 적당한 라이브러리를 찾기 위한 목적으로 사용된다. 설정파일은 다음과 같이 구성된다. 설정파일의 이름은 plugin.cfg 로 하겠다.
blowfish,libblowfish,blowfish 알고리즘
mycrypt,libmycrypt,사용자 정의 암호화 알고리즘
null,libnull,null function 알고리즘
3개의 필드를 가진다. 첫번째 필드에는 암호화이름 두번째 필드는 불러들일 라이브러리 이름, 세번째 필드는 간단한 설명이다.
암호화할때는 파일의 가장앞에 암호화된 파일의 정보구조체를 집어 넣을것이다. 이 구조체는 다음과 같다.
다음은 실제코드이며, 설명은 주석으로 대신하도록 한다.
예제 : fcrypt.c
fcrypt.c 는 다음과 같이 컴파일하면 된다. [root@localhost crypt2]# gcc -o fcrypt fcrypt.c -ldl -lcrypto
--------------------------------------------------------------------------------
3.3.3절. blowfish.c
이것은 fcrypt 프로그램에서 동적으로 적재할 플러그인 프로그램으로 blowfish 알고리즘을 통해서 주어진 파일을 암호화 하고 복호화 한다.
blowfish 는 앞에서 말했듯이 암호화에 사용된 key 를 가지고 복호화를 하게 된다. 당연히 이러한 key 데이타를 파일로 저장하고 있어야 할것이다.
그럼으로 blowfish 는 파일을 암호화 하게 될경우 암호화된 파일과 암호화에 사용된 key 를 저장하는 파일 이렇게 2개의 파일을 생성한다. 암호화된 파일은 원본파일뒤에 ".cry" 를 붙이고, key 파일은 원본파일 뒤에 ".key"를 붙이도록 해서 생성하도록 할것이다.
key 사이즈는 128 bit 로 할것이다. 이 blowfish 는 openssl 의 crypto 라이브러리에서 제공한다. 그리고 랜덤한 key 를 생성하기 위해서 /dev/random 커널 난수 생성기를 이용할것이다. 커널 난수 생성기에 대해서는 random 값 얻어오기를 참고하기 바란다.
crypto 에서 제공하는 blofish 암호화 알고리즘에는 key 외에도 initalization vector 가 필요하다. 이것의 크기는 64bit 로 할것이며, 마찬가지로 /dev/random 을 이용해서 랜덤하게 생걱할것이다. 고로 실제 key 파일에는 key 값과 initalization vector 값이 저장될 것이다.
그리고 Cipher Block Chaining(CBC) 모드 상태에서 암/복호화를 하게 될것이다.
예제 : blowfish.c
blowfish.c 는 공유라이브러리 형태로 만들어줘야 한다. 다음과 같이 공유라이브러리 형태로 만들어주자. [root@localhost crypt2]# gcc -c -fPIC blowfish.c
[root@localhost crypt2]# gcc -shared -W1,-soname,libblowfish.so.1 -o libblowfish.so.1.0.1 blowfish.o
이렇게 하면 libblowfish.so.1.0.1 이라는 라이브러 파일이 만들어 진다. 이 파일은 plugin 디렉토리를 만들어서 복사하고 다음과 같이 심볼릭 링크를 걸어주도록 하자.
[root@localhost crypt2]# mkdir plugin
[root@localhost crypt2]# cp libblowfish.so.1.0.1 plugin/
[root@localhost crypt2]# cd plugin
[root@localhost plugin]# ln -s libblowfish.so.1.0.1 libblowfish.so
--------------------------------------------------------------------------------
3.4절. 테스트
테스트를 하기 위해서는 plugin.cfg 파일이 있어야 하며, plugin 디렉토리 밑에 해당 암호화 알고리즘을 지원하는 라이브러리가 존재하고 있어야 한다. 다음은 필자의 plugin.cfg 의 파일이다.
blowfish,libblowfish.so,blowfish 알고리즘
null,libnull.so,null function 알고리즘
blowfish 는 무엇인지 알테고, null 은 필자가 동적라이브러리 테스트용으로 만든 것으로 말그대로 null 이다. 즉 아무런 암호화 과정없이 그대로 원본내용을 그대로해서 암호화파일을 만든다. 각자 만들어 보기 바란다.
plugin 밑에는 다음과 같은 파일들이 있다.
[root@localhost plugin]# ls
libblowfish.so libblowfish.so.1.0.1 libnull.so libnull.so.1.0.1
이제 테스트를 해보자, 테스트 결과의 확인을 쉽게 하기 위해서 text 파일을 테스트에 사용하도록 하자. 필자는 fcrypt.c 를 암호화/복화화 테스트에 사용하도록 했다.
다음은 암호화 테스트로 fcrypt.c 를 blowfish 알고리즘을 사용한 테스트 결과이다.
[root@localhost crypt2]# ./fcrypt -c fcrypt.c -t blowfish
ok encrypt
실행결과 암호화된 파일인 fcrypt.c.cry 와 key 가 저장된 fcrypt.c.key 가 생성되었음을 확인할수 있을것이다.
다음은 암호화된 파일의 정보를 얻어오는 테스트이다.
[root@localhost crypt2]# ./fcrypt -i fcrypt.c.cry
Version : 1.0
crypttype : blowfish
다음은 fcrypt 가 현재 지원하는 plug in 알고리즘의 목록을 출력한 것이다.
[root@localhost crypt2]# ./fcrypt -l
blowfish libblowfish.so blowfish 알고리즘
null libnull.so null function 알고리즘
다음은 복호화 시킨 결과이다.
[root@localhost crypt2]# ./fcrypt -d fcrypt.c.cry -t blowfish -k fcrypt.c.key
--------------------------------------------------------------------------------
4절. 결론
이상 openssl 을 이용한 암호화방법에 대해서 알아보았다. 위의 예제 프로그램들은 수정해야할 여지가 많을것이다.
여기에서는 단지 파일만을 예로 들었지만, 네트웍 프로그래밍등에도 충분히 응용이 가능할것이다.
출처 : http://joinc.co.kr/modules.php?name=new ··· 3Dnested
"UNIX/Linux C" 카테고리의 다른 글
- 터미널 제어 (0)2007/05/14
- random 값 얻어오기 (0)2007/05/14
- openssl 을 통한 데이타 암호화 (0)2007/05/14
- pthread API 레퍼런스 (3)2007/05/14
- 안전한 프로그래밍 (0)2007/05/11

수안이의 컴퓨터 연구실



Leave your greetings.