RSA 알고리즘으로 작업할 일이 있어서 테스트 페이지를 만들어 보았다. session으로 작업되어있는 소스를 웹에서 발견하였으나, session은 약간 문제가 될 소지가 있어서 ehcache를 이용해서 작업해 보았다.
그리고 재활용을 위해 클래스로 묶어보았다. 지극히 개인적인 이유로 만들었으므로 간단하다.
1. 자바에서 할일
키생성
public void keyGen(final String keyIndex) throws ServletException, IOException{
try{
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(KEY_SIZE);
KeyPair keyPair = generator.genKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey pKey = keyPair.getPrivate();
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
// 캐시에 공개키의 문자열을 키로하여 개인키를 저장한다.
this.setCache(keyIndex, pKey);
// 공개키를 문자열로 변환하여 JavaScript RSA 라이브러리 넘겨준다.
RSAPublicKeySpec publicSpec = (RSAPublicKeySpec) keyFactory.getKeySpec(publicKey, RSAPublicKeySpec.class);
privateKey = null;
publicKeyModulus = publicSpec.getModulus().toString(16);
publicKeyExponent = publicSpec.getPublicExponent().toString(16);
LOG.info("create publicKeyModulus : " + publicKeyModulus );
LOG.info("create publicKeyExponent : " + publicKeyExponent );
} catch (Exception ex) {
throw new ServletException(ex.getMessage(), ex);
}
}
publicKeyModulus, publicKeyExponent, privateKey키는 항상 사용하기 때문에 전역변수로 선언해주었다. 그리고 POJO안에 RSA에 필요한 소스들이 전부 들어있다. 가져다 사용하면되는 것이다.
복호화
public String getDecodeStr(final String keyIndex, final String rsaCode) throws ServletException, IOException {
String ret = null;
if(privateKey == null){
this.getCache(keyIndex);
}
if (privateKey == null) {
throw new RuntimeException("암호화 비밀키 정보를 찾을 수 없습니다.");
}
try {
ret = decryptRsa(privateKey, rsaCode);
} catch (Exception ex) {
throw new ServletException(ex.getMessage(), ex);
}
return ret;
}
rsaCode는 javascript에서 암호화한 코드이다.
사용예
//키생성
try{
cacheRsa.keyGen("__rsaPrivateKey__");
model.put("publicKeyModulus", cacheRsa.getPublicKeyModulus());
model.put("publicKeyExponent", cacheRsa.getPublicKeyExponent());
}catch(Exception e){
System.out.println("/rsa/incode --> 키 생성 실패");
}
//복호화
String tmp = cacheRsa.getDecodeStr("__rsaPrivateKey__", rsaCode);
2. 화면단에서 할 일
초기화
<script type="text/javascript" src="/js/rsa/jsbn.js"></script>
<script type="text/javascript" src="/js/rsa/rsa.js"></script>
<script type="text/javascript" src="/js/rsa/prng4.js"></script>
<script type="text/javascript" src="/js/rsa/rng.js"></script>
<script type="text/javascript" src="/js/rsa/rsaUtil.js"></script>
<script type="text/javascript">
var modulus = "${publicKeyModulus?default('')}";
var exponent = "${publicKeyExponent?default('')}";
var forwardingUrl = "/rsa/decode.free";
var rsaGen = new RsaUtil(modulus, exponent, forwardingUrl);
</script>
rsaUtil.js라고 하나 만들어주었다. 별거 없고 안에서 초기화와 form을 관리해준다.
사용예
<script type="text/javascript">
function submitText(){
for(var i=0; i < 30; i++){
rsaGen.addItem('rsaCode');
//rsaGen.addData('rsaCode', '가나다라마바사아자차카타파하 1234567890');
}
rsaGen.rsaSubmit();
}
</script>
textInput: <input id="rsaCode" type="text" /><input type="button" value="전송" onclick="javascript:submitText();" />
전송버튼을 누르면 자바스크립트에서 rsaCode라는 input태그를 만들어 하단의 rsaCode id를 가지는 태그에서 값을 가져와 암호화한다. 512바이트 암호화를 사용했는데 문자길이가 걱정되어 얼마나 될까하고 30번 넣어봤다 ㅋㅋ.
결과는 잘나온다. 하지만 54이상은 너무 길다는 메시지를 출력한다. 1024바이트 암호화의 경우 100자 이상도 가능하나 150자는 안된다. 한글은 한번에 17자까지 전송이 가능하다. utf-8방식으로 변경하기때문이다. 암호화 가능한 길이나 url 길이가 제한있다보니 이런것도 테스트해봐야한다. 정확한 것은 안니지만, post방식 form은 상당히 긴 길이도 전송이 가능한듯 하다.
추가로 알아야할 것은 ehcache설정이다. 나는 spring에서 별도로 설정한 것이 없고 checache.xml만 설정했다. 아래 링크를 참고하자.
rsa 참고한 페이지: http://kwon37xi.egloos.com/4427199
ehcache 참고한 페이지:
http://ehcache.org/documentation
http://sonegy.wordpress.com/2011/12/29/spring-3-1%EA%B3%BC-ehcache/
http://javacan.tistory.com/entry/133
http://byteco.de/2010/01/26/integrating-spring-and-ehcache/
작업한 프로젝트 첨부, 프로젝트를 루트로 했기때문에 경로를 /으로 맞추고 하거나 수정해야한다.
'encryption' 카테고리의 다른 글
JAVA MessageDigest 클래스 (0) | 2015.04.20 |
---|