package common;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
* 1.DES, TripleDES 암호화, 복호화
* 2.생성될 키는 암호화할때와 복호화시 같은 키를 사용해야한다.
* 3.화면에 출력할 수 없는 문자 표시를 위해 BASE64 사용
*/
public class CryptoUtil {
public CryptoUtil() {
}
/**
* 16byte : DES
* 24byte : TripleDES
*
* 문자열이 해당 byte의 크기만 되면 어떤 내용이든 상관 없음.
* @return String 키값
*/
private static String key() {
//return "ab_booktv_abcd09"; //DES
return "12_123ktv_123d09"; //DES
//return "ab_booktv_abcd0912345678"; //TripleDES
}
/**
* 24바이트인 경우 TripleDES 아니면 DES
* @return Key
* @throws Exception
*/
private static Key getKey() throws Exception {
return (key().length() == 24) ? getKey2(key()) : getKey1(key());
}
/**
* Cipher의 instance 생성시 사용될 값
* @return String DES, TripleDES 구분
* @throws Exception
*/
private static String getInstance() throws Exception {
return (key().length() == 24) ? "DESede/ECB/PKCS5Padding" : "DES/ECB/PKCS5Padding";
}
/**
* 지정된 비밀키를 가지고 오는 메서드(DES)
* require Key Size : 16bytes
*
* @param keyValue
* @return Key
* @throws Exception
*/
private static Key getKey1(String keyValue) throws Exception {
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
DESKeySpec desKeySpec = new DESKeySpec( keyValue.getBytes() );
return keyFactory.generateSecret( desKeySpec );
}
/**
* 지정된 비밀키를 가지고 오는 메서드(TripleDES)
* require Key Size : 24bytes
*
* @param keyValue
* @return Key
* @throws Exception
*/
private static Key getKey2(String keyValue) throws Exception {
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
DESKeySpec desKeySpec = new DESKeySpec( keyValue.getBytes() );
return keyFactory.generateSecret( desKeySpec );
}
/**
* 문자열 대칭 암호화
* return String 암호화된 문자열
*/
public static String encrypt(String input) throws Exception {
if(input == null || input.length() == 0) return "";
Cipher cipher = Cipher.getInstance( getInstance() );
cipher.init( Cipher.ENCRYPT_MODE, getKey() );
byte [] inputBytes = input.getBytes("UTF8");
byte [] outputBytes = cipher.doFinal( inputBytes );
return new BASE64Encoder().encode( outputBytes );
}
/**
* 문자열 대칭 복호화
* return String 복호화된 문자열
*/
public static String decrypt(String input) throws Exception {
if(input == null || input.length() == 0) return "";
Cipher cipher = Cipher.getInstance( getInstance() );
cipher.init( Cipher.DECRYPT_MODE, getKey() );
byte [] inputBytes = new BASE64Decoder().decodeBuffer( input );
byte [] outputBytes = cipher.doFinal( inputBytes );
return new String( outputBytes, "UTF8" );
}
}
String encrypt = CryptoUtil.encrypt("1234");
String decrypt = CryptoUtil.decrypt(encrypt);
jsp에서 암호화후 servlet에서 복호화 하여도 제대로 복호화가 된다.
암호화시 생성한 키와 복호화시 생성한 키가 같아야 제데로 복화가 되는데..
new DESKeySpec 을 사용하여 동일한 스펙을 생성후 키를 생성하면 생성시 똑같은 키가 생성된다.
스펙을 사용하지 않고 키 생성시 항상 다른키가 생성 되기 떄문에 스펙을 사용하자.
jsp에서 스팩없이 키 생성후 메모리에 올려서 servlet쪽에서 똑같은 키로 복호화 해보았지만
같은 키임에도 불구하고 복호화시 다른값이 나온다.
메모리에서 키를 가져올때 해당 키의 복사본을 가져와서 사용하기 때문에 값이 다른게 아닌가 한다.
공부를 좀더 해봐야겠다.
혹시 아시는분은 댓글로 답변 해주시면 감사하겠습니다..^^;
참고 : http://manseya.blog.me/50070479326
http://kwon37xi.egloos.com/4427199
http://blog.mr.hanul.co/2011/10/java-javascript-secure-transfer.htm
'Java' 카테고리의 다른 글
[Java] 고수를 위한 시각 교정, 업그레이드된 개발자 되기 (0) | 2011.06.13 |
---|---|
[Java] Java - Jabook.chm 문서 (0) | 2011.05.17 |
[Java] Base64 - 2 (0) | 2011.03.24 |
[Java] Base64 - 1 (0) | 2011.03.24 |
[Java] java warning: no definition of serialVersionUID (0) | 2011.03.02 |