2018. 2. 23. 10:53
반응형

RSA 암호화 방식 구조

1. server에서 public, private 키를 생성해서 public 키만 client에 전송

2. client에서 public키로 평문을 암호화 해서 server에 전송

3. server에서 전달된 암호문을 private키로  복호화 처리


RSA 암/복호화 JAVA 구현 CLASS 특이사항

1024 bit RSA 암호화 방식으로 initialize 값을 변경하면 512 bit 방식이나 2048 bit 방식으로도 변경 가능함.

bit가 올라갈수록 키, 암호화된 값이 길어지며 소요 시간이 길어짐.

키 spec을 문자열로 가져오는 과정에서 편의상 modulus와 exponent값을 /로 구분해서 합쳤기 때문에

타 시스템에서 사용하기 위해서는 /로 split 필요함.


CLASS 내용

import java.math.BigInteger;

import java.security.Key;

import java.security.KeyFactory;

import java.security.KeyPair;

import java.security.KeyPairGenerator;

import java.security.spec.RSAPrivateKeySpec;

import java.security.spec.RSAPublicKeySpec;


import javax.crypto.Cipher;


import org.bouncycastle.util.encoders.Base64;


public class TestRSA {

private Key publicKey;

private Key privateKey;

/**

* 개인키로 복호화 한다.

* @param txt

* @return

* @throws Exception

*/

public String decode(String txt) throws Exception {

Cipher c = Cipher.getInstance("RSA");

c.init(Cipher.DECRYPT_MODE, privateKey);

return new String(c.doFinal(Base64.decode(txt.getBytes("UTF-8"))));

}

/**

* 공개키로 암호화 한다.

* @param txt

* @return

* @throws Exception

*/

public String encode(String txt) throws Exception {

Cipher c = Cipher.getInstance("RSA");

c.init(Cipher.ENCRYPT_MODE, publicKey);

return new String(Base64.encode(c.doFinal(txt.getBytes("UTF-8"))));

}

/**

* 공개키, 개인키 한쌍을 생성한다.

* @throws Exception

*/

public void generatorKey() throws Exception {

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");

keyPairGenerator.initialize(1024);

KeyPair keyPair = keyPairGenerator.genKeyPair();

publicKey = keyPair.getPublic();

privateKey = keyPair.getPrivate();

}

/**

* 공개키 문자열을 가져온다.

* @return

* @throws Exception

*/

public String getPublicKeySpecStr() throws Exception {

RSAPublicKeySpec publicKeySpec = KeyFactory.getInstance("RSA").getKeySpec(publicKey, RSAPublicKeySpec.class);

return publicKeySpec.getModulus() + "/" + publicKeySpec.getPublicExponent();

}

/**

* 공개키 문자열로 공개키를 생성한다.

* @param specStr

* @throws Exception

*/

public void setPublicKeySpecStr(String specStr) throws Exception {

String[] specArr = specStr.split("/");

setPublicKeySpecStr(specArr[0], specArr[1]);

}

/**

* 공개키 문자열로 공개키를 생성한다.

* @param modulus

* @param exponent

* @throws Exception

*/

public void setPublicKeySpecStr(String modulus, String exponent) throws Exception {

RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(new BigInteger(modulus), new BigInteger(exponent));

publicKey = KeyFactory.getInstance("RSA").generatePublic(publicKeySpec);

}

/**

* 개인키 문자열을 가져온다.

* @return

* @throws Exception

*/

public String getPrivatekeySpecStr() throws Exception {

RSAPrivateKeySpec privateKeySpec = KeyFactory.getInstance("RSA").getKeySpec(privateKey, RSAPrivateKeySpec.class);

return privateKeySpec.getModulus() + "/" + privateKeySpec.getPrivateExponent();

}

/**

* 개인키 문자열로 개인키를 생성한다.

* @param specStr

* @throws Exception

*/

public void setPrivateKeySpecStr(String specStr) throws Exception {

String[] specArr = specStr.split("/");

setPrivateKeySpecStr(specArr[0], specArr[1]);

}

/**

* 개인키 문자열로 개인키를 생성한다.

* @param modulus

* @param exponent

* @throws Exception

*/

public void setPrivateKeySpecStr(String modulus, String exponent) throws Exception {

RSAPrivateKeySpec privateKeySpec = new RSAPrivateKeySpec(new BigInteger(modulus), new BigInteger(exponent));

privateKey = KeyFactory.getInstance("RSA").generatePrivate(privateKeySpec);

}

public static void main(String[] args) throws Exception {

// 서버단 키 생성

TestRSA serverRSA = new TestRSA();

serverRSA.generatorKey();

String publicKeySpec = serverRSA.getPublicKeySpecStr();

String privateKeySpec = serverRSA.getPrivatekeySpecStr();

// 클라이언트단 공통키로 암호화

TestRSA clientRSA = new TestRSA();

String originalTxt = "이 문자열을 보냅니다.";

clientRSA.setPublicKeySpecStr(publicKeySpec);

String encodeTxt = clientRSA.encode(originalTxt);

// 이미 생성된 서버 자원 사용

String decodeTxt = serverRSA.decode(encodeTxt);

// 서버에서 새 자원 생성해서 개인키로 복호화

TestRSA serverRSARe = new TestRSA();

serverRSARe.setPrivateKeySpecStr(privateKeySpec);

String decodeTxtRe = serverRSARe.decode(encodeTxt);

System.out.println("publicKeySpec : " + publicKeySpec);

System.out.println("privateKeySpec : " + privateKeySpec);

System.out.println("originalTxt : " + originalTxt);

System.out.println("encodeTxt : " + encodeTxt);

System.out.println("decodeTxt : " + decodeTxt);

System.out.println("decodeTxtRe : " + decodeTxtRe);

}

}

반응형

'Java' 카테고리의 다른 글

java Object deep clone 비교  (0) 2022.06.29
tomcat localhost ssl 적용을 위한 키 생성  (0) 2021.02.05
goo.gl api java 구현  (0) 2016.10.06
bit.ly api java 구현  (0) 2016.10.06
Object와 Object[]에 대한 내용  (1) 2011.11.10
Posted by seongsland