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 |