안녕하세요! 티스토리에서 처음으로 인사드리는 신입 프로그래머 호파 입니다.


제 첫번째 포스트를 암호화 시리즈로 시작하려 합니다.

개발 업무를 하다보면 웹프로그래머로 있어서 그런지

다른 업체와 협업을 할 때 주로 RestFul API를 통해 작업을 진행합니다.

그 안에서 사용자 개인정보를 포함한 중요정보들을 암호화하여 넘겨 받게 됩니다.


이렇게 많이 쓰이는 암호화를 첫 글로 작성하면서 다른 개발자들에게 참고용 포스트가 됨과 동시에

스스로 공부한 것을 정리해 내것으로 만듦과 많은 개발자들과의 소통과 조언을 기다립니다.




- AES 소개


AES(Advanced Encryption Standard)


1997년 1월 2일, 미국 국립표준기술연구소 'NIST' 는 기존 DES를 대체할 목적으로 더 나은 암호기법을 공모하였다.


기존 DES(Data Encryption Standard)는 블록 암호로 표준으로 두고 있었는데 56비트 대칭키 암호화로 현재 컴퓨터 환경에 비해 너무 짧고 특수한 방법을 사용하면 쉽게 해독할 수 있는 주장이 제기되면서(이는 실제로 약 22시간만에 풀 수 있는 해독알고리즘이 구현되었다.)  새로운 표준의 암호화를 공모하였고 약 30개의 공모된 알고리즘을 1차심사를 거쳐 최종심사를 받게 될 5개의 알고리즘을 선정했다.


MARS : IBM 연구소 제출

RC6 : RSA Security 제출

Serpent : Ross Andersen, Eil Biham, Lors Knudsen 공동 제출

Twofish : Counterpane의 암호학자 bruce Schneier를 비롯한 대규모 연구팀 제출

Rijandael : 벨기에 암호학자 Joan Daemen, Vincent Rijmen 공동 제출


위 알고리즘은 모두 C, Java 언어를 이용하였고 '안전성', '비용', '알고리즘 및 구현 특성' 이란 세 가지 조건을 기준으로 평가받게 되었다.

이 안에서 Rijandael 알고리즘이 안전성, 속도, 효율성, 구현 및 유연성이 다른 알고리즘들 보다 우수하다 평가했고 2000년 10월 2일, AES 암호화/복호화 알고리즘으로 Rijandael을 선정하게 되었다.



- AES 특징


1. 대칭 키 알고리즘

2. 빠르고 공격에 대해 안전하다.

3. 간단한 하드웨어 / 소프트웨어로 구성하기 쉽다.

4. 128비트의 블록 크기 값을 가진다.

5. 기본적으로 128, 192, 256 비트 키 값을 가지나 이론적으로 키의 크기 제한이 없다.



- AES 알고리즘 (Java 코드)

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.net.util.Base64;

public class AES {

	/** 암호키 (임의지정) */
	String encryptKey = "dladmlwlwjd";

	public String encrypt(String inputStr){
 
		String result = null;
  
		if ((inputStr == null) || (inputStr.length() < 1)) {
			return result;
		}
  
		SecretKeySpec keySpec = new SecretKeySpec(encryptKey.getBytes(), "AES");
		
		try {
			Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
			cipher.init(1, keySpec);
    
			byte[] byteValue = cipher.doFinal(inputStr.getBytes("UTF-8"));

			Base64 base64EnDe = new Base64();            

			result = base64EnDe.encodeToString(byteValue).replaceAll("\r\n", "");
		}
		catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		
		return result;
	}
	
	
	public String decrypt(String encStr){
	
		String result = "";
	
		if ((encStr == null) || (encStr.length() < 1)) {
			return result;
		}
		
		SecretKeySpec keySpec = new SecretKeySpec(encryptKey.getBytes(), "AES");
		
		try {
			Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
			cipher.init(2, keySpec);
	  
			Base64 base64EnDe = new Base64();            

			byte[] origianl = cipher.doFinal( base64EnDe.decode(encStr) );
	 
			result = new String(origianl, "UTF-8");
			
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		}
	
		return result;
	}
}


+ Recent posts