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