본문 바로가기

보안공부/암호학

암호학 2번째 이야기

반응형
참조 : http://www.hackerschool.org/HS_Boards/data/Lib_encrypt/cross.txt
대칭암호화알고리즘 소개 및 DES, Blowfish샘플코드 

 
대칭암호화알고리즘이 무엇인지 간략히 소개하고, JCA-JCE및 간단한 두가지 알고리즘을 
획득하여 암호화 하는 방법을 소개하고자 한다. ( 2003/06/23 )


Written by ienvyou - 최지웅  http://www.javapattern.info/viewArticle.do?articleId=1056353892296

오랫만이 쓰는 아티클인것 같다. 여기서는 우선 맛보기로 간단하게 암호화에 대한 내용 및
대칭암호방법에 대한 내용을 설명하도록 하겠다.

요즘 같이 인터넷이 보편화되고 개방형 시스템들이 존재하게 되면서 개인의 정보및
비밀에 대한 정보보호가 굉장한 이슈로 대두되어지고 있다.

우리가 사용하게 되는 자바는 java.security및 javax.crypto패키지를 통하여 암호를 쉽게
사용할 수 있는 기능을 제공한다. 
만약 당신이 어떠한 데이터를 다른 사람에게 전달하던 도중 그 메시지를 다른 사람이 보게
된다면? 그게 만약 신용카드나 결제정보, 중요한 문서일수도 있는 것이다.
그러한 것들에 대한 침입위험으로부터 정보가 보호되어지기 위해서는 무언가의 수단이
필요하게 될것이다. 자바측에서도 코드정책에 대한 보안이 필요하겠지만 우선은
기본적인 사항만을 여기서 논하겠다.

기본적인 자바의 코드보안정책으로서 final class라든지, 패키지보안, jar파일 sign, 
serialization부분의 transient등에 대한 설명은 여기서 논의하지 않도록 하겠다.

▶ 대칭암호화 알고리즘

기본적으로 이 글을 읽는 사람이라면 학교다닐때 한번쯤은 친한 친구와의 의사소통이나
대화를 하는데에 있어서 남들이 알지 못하는 방법으로 대화를 하고 싶었던 적이 있을것이다.
(놀새~만 그랬나?) 
가령 내가 고등학교를 다닐때 친구와 이야기를 할때 모든 단어를 표현하고자 할때
중성을 뒤로 빼서 그것을 이용하여 한글자를 더 만들고 거기에 ㅅ받침을 이용하여 의사소통을
한적도 있었다. (예: 비둘기 --> 비시 두술 기시) 처럼말이다..

위의 예를 든것도 일종의 암호화의 한 방법이라고 할 수 있는데 일반 사람들이 듣기에는
어떠한 논리에 의하여 말을 하는 것인지 처음에는 알아듣지를 못하다가 단어를 적어주거나
한참후에야 그러한 원리가 있었음을 알게 된다.

위와 같이 암호화와 같은 정보를 이용하여 다시 복호화 할수 있는 데 좀 더 쉽게 예를 들어보자면
다음과 같을 수 있다.


A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
|                               
D E F G H I J K L M N O P Q R S T U V W X Y Z A B C 

각각의 문자를 3자리씩 뒤로 옮겨진 것 처럼 보여질 수 있는데  만약 HI, CAROUSER라는 단어는
KL, FDURXVIU 라는 단어로 바뀌게 되면 같은 패턴에 의하여 다시 복호화 되어질수 있는 
특징을 가지고 있다.
즉 메시지를 암호화와 복호화를 하기 위해서는 알고리즘과 키가 정의되어야 한다.

▶ 대칭암호화 알고리즘의 종류



    
DES & TripleDES : DES(Data Encryption Standard)는 "Lucifer"라는 이름의 IBM에서 최초개발되었다.
    또한 미국에서 최초 국가표준이 되었으며, 56비트키를 가지고 암복호화를 사용했다. 하지만
    컴퓨터가 발전을 함에 있어서 56비트키의 경우 어느정도의 시간만 확보가 된다면 풀어낼수 있기
    때문에 좀더 완벽한 보안을 위하여 Triple DES가 고안되어졌다.
    
TripleDES : 이는 기존의 DES암호화 알고리즘방식을 다른키에 세번 적용시킨것이며, 첫번째
    암호화과정, 두번째 복호화과정, 세번째는 또 다른 암호화 과정을 거치도록 하고 있다.
    그래서 이름이 DESede(DES encryption, decryption, encryption)이 되었으며, 각각의 과정에 따라
    56비트의 배수로 암호화 복잡도가 증가되게 되어있다.
    
Blowfish : 1993년 Bruce Schneier에 의해 고안된 블록암호로서 DES보다 빠르고 안전한 기법을
    제공한다. 최대 키의 비트수를 448비트까지 확장할수있다는 특징을 가지고 있다.
    
RC4 : "Civest's Code 4"를 의미하며 1987년 RSA Data Security에서 발표되었다. 보통 이기법으로
    TCP/IP연결을 안전하게 하는 SSL을 구현하는 데 많이 쓰인다(키의 길이 40비트 또는 128비트)



위과 같이 대칭암호화의 경우는 모든 알고리즘이 같은 방식으로 동작을 하게 되는데
문제는 메시지를 보내고 받는 사람이 같은 키를 가지게 되며, 중간에 그 키가 노출이 되었을 땐
이미 우리의 메시지는 남에게 읽힐수 있는 문제점을 가지고 된다. 즉 비밀키가 노출되게 되면
암호화된 메시지또한 동시에 노출될 수 있다는 단점을 가지고 있다.

▶ DES방식의 샘플코드

우리는 여기서 간단하게 DES방식을 이용하여 암복호화 프로그램을 하나 예제로 보도록 한다.
기본적으로 자바측에서 제공할수 있는 암호에 관련된 패키지는 JCA(java cryptograhpy arch.)와
JCE(java cryptography extension)을 사용할 수 있다. 
JCA는 기본적으로 Java2 Runtime Environment의 일부이며, JCA는 그것의 확장패키지이다.
기본적인 JCA에서는 전자서명, 메시지 다이제스트, 키생성기등의 클래스를 가지고 있으며
그러한 기본적인 클래스들을 우리가 사용하고자 했을 때 new에 의한 생성이 아니라
이미 아키텍쳐가 가지고 있는 암호화 기법에 의하여 factory형태의 클래스에게 생성을
요청하여야 한다. 
기본적인JCE같은 경우 당신이 JDK1.3.1을 사용한다면 패키지를 썬에서 다운로드 받을수있으며
jdk1.4버젼을 사용한다면 이미 포함되어져 있으니 그냥 코딩을 해도 무방할 듯 하다.


우선 아래의 코드를 보기 전에 중요한 클래스를 살펴보아야 할 필요가 있는데 그것은 
바로 javax.crypto.Cipher라는 클래스로서 데이터를 암호화하고 복호화하는데 사용되는
기본적인 엔진부분이다. 

몇가지의 메소드만을 살펴보겠는데 우선 
getIntance(), init(), update(), doFinal()로서 암호화 알고리즘의 생성, Cipher인스턴스의 초기화,
암복호화, 암호화된 배열을 획득을 하는 메소드들이다.

또한 javax.crypto.KeyGenerator클래스는 암호화와 복호화에 필요한 키를 생성해내는 데 쓰이며
getInstance(), init(), generateKey()의 메소드 정도면 Cipher에 필요한 키를 만들어낼 수 있다.


import java.security.*;
import javax.crypto.*;

public class SimpleExample {
    public static void main(String [] args) throws Exception {
        if( args.length != 1) {
            System.out.println("Usage : java SimpleExample text ");
            System.exit(1);
        }
        String text = args[0];

        System.out.println("Generating a DESded (TripleDES) key...");

        // Triple DES 생성
        KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede");
        keyGenerator.init(168);	// 키의 크기를 168비트로 초기화
        Key key = keyGenerator.generateKey();

        System.out.println("키생성이 완료되었음");

        // Cipher를 생성, 사용할 키로 초기화
        Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);

        byte [] plainText = text.getBytes("UTF8");

        System.out.println("Plain Text : ");
        for (int i = 0; i < plainText.length ; i++)	{
            System.out.print(plainText[i] + " ");
        }

        // 암호화 시작
        byte [] cipherText = cipher.doFinal(plainText);

        // 암호문서 출력

        System.out.println("\nCipher Text : ");
        for (int i = 0; i < cipherText.length ; i++)	{
            System.out.print(cipherText[i] + " ");
        }

        //복호화 모드로서 다시 초기화
        cipher.init(Cipher.DECRYPT_MODE, key);

        //복호화 수행

        byte [] decryptedText = cipher.doFinal(cipherText);
        String output =  new String(decryptedText, "UTF8");
        System.out.println("\nDecrypted Text : " + output);
    }
};

 


위의 코드로서 간단하게 살펴볼 수 있는데, 출력되는 생성되는 키에 따라 결정되므로
매번 다른 결과의 암호화된 문자열을 볼 수 있는 특징을 가지고 있다. 

Blowfish의 대칭암호화 기법또한 같은 방법에 의하여 만들어낼 수 있는데
단순히 위의 코드상에서의 변화는 KeyGenerator에서 "Blowfish"와 Cipher에서
인스턴스를 얻어낼때 단순히 "Blowfish/ECB/PKCS5Padding"을 이용하여 처리하면
128비트의 키를 이용한 암복호화를 테스트해볼 수 있다.

▶ Conclusion

기본적으로 가장 기본적인 암호화 방법을 살펴보았으며 기본적인 대칭알고리즘의 개념이
무엇인지만 알고 있어도 놀새~가 여러분들을 보는 기준에서 별 무리가 없어 보일듯 하다.

다음에 쓸 것으로는 유닉스 패스워드의 형태로 많이 쓰이는 메시지 다이제스트방법을
간단한 자바코딩을 이용하여 처리해보겠다.
위의 경우 웹사이트를 직접 만들었을 경우 사용자들에 대한 user id, password를 
데이터베이스에 직접저장하는 것이 아니라 universal key의 개념으로 변환하여
처리하는 샘플을 보도록 하겠다.. 
정리 :  
1. key는 key가 사용할 공간을 잡는다
2. cipher는 key를 알고리즘을 적용해서 실제 key를 만들어 낸다 (암호화모드로)
3. 입력한 문장을 알고리즘을 적용하여 암호화한다
4. cipher는 key를 알고리즘을 적용해서 실제 key를 만들어 낸다 (복호화모드로)
5. 암호화된 문장을 알고리즘을 적용하여 복호화하여 실제 문장을 얻어낸다.
반응형