Java RSA 암호화/복호화 구현
Java RSA Encryption Decryption
Public Key로 평문을 암호화 -> 암호문
-> Private Key로 암호문 복호화 -> 평문
/**
* Developer : ryan kim
* Date : 2020-05-21
*/
public class RSAUtil {
/**
* 1024비트 RSA 키쌍을 생성
*/
public static KeyPair genRSAKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
gen.initialize(1024, new SecureRandom());
return gen.genKeyPair();
}
/**
* Public Key로 RSA 암호화를 수행
*/
public static String encryptRSA(String plainText, PublicKey publicKey)
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException,
BadPaddingException, IllegalBlockSizeException {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] bytePlain = cipher.doFinal(plainText.getBytes());
return Base64.getEncoder().encodeToString(bytePlain);
}
/**
* Private Key로 RSA 복호화를 수행
*/
public static String decryptRSA(String encrypted, PrivateKey privateKey)
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException,
BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {
Cipher cipher = Cipher.getInstance("RSA");
byte[] byteEncrypted = Base64.getDecoder().decode(encrypted.getBytes());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] bytePlain = cipher.doFinal(byteEncrypted);
return new String(bytePlain, "utf-8");
}
public static PublicKey getPublicKeyFromBase64Encrypted(String base64PublicKey)
throws NoSuchAlgorithmException, InvalidKeySpecException {
byte[] decodedBase64PubKey = Base64.getDecoder().decode(base64PublicKey);
return KeyFactory.getInstance("RSA")
.generatePublic(new X509EncodedKeySpec(decodedBase64PubKey));
}
public static PrivateKey getPrivateKeyFromBase64Encrypted(String base64PrivateKey)
throws NoSuchAlgorithmException, InvalidKeySpecException {
byte[] decodedBase64PrivateKey = Base64.getDecoder().decode(base64PrivateKey);
return KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(decodedBase64PrivateKey));
}
}
/**
* Developer : ryan kim
* Date : 2020-05-21
*/
public class RSAUtilTest {
@Test
public void RSA_Base64_암복호화_테스트()
throws NoSuchAlgorithmException, IllegalBlockSizeException, InvalidKeyException,
BadPaddingException, NoSuchPaddingException, UnsupportedEncodingException,
InvalidKeySpecException {
// RSA 키쌍을 생성
KeyPair keyPair = RSAUtil.genRSAKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
String plainText = "RSA Encryption test";
// Base64 인코딩된 암호화 문자열
String encrypted = RSAUtil.encryptRSA(plainText, publicKey);
// 복호화
String decrypted = RSAUtil.decryptRSA(encrypted, privateKey);
Assert.assertEquals(plainText, decrypted);
// 공개키를 Base64 인코딩한 문자일을 만듦
byte[] bytePublicKey = publicKey.getEncoded();
String base64PublicKey = Base64.getEncoder().encodeToString(bytePublicKey);
// 개인키를 Base64 인코딩한 문자열을 만듦
byte[] bytePrivateKey = privateKey.getEncoded();
String base64PrivateKey = Base64.getEncoder().encodeToString(bytePrivateKey);
// base64 암호화한 String 에서 Public Key 를 다시생성한후 암호화 테스트를 진행
PublicKey rePublicKey = RSAUtil.getPublicKeyFromBase64Encrypted(base64PublicKey);
String encryptedRe = RSAUtil.encryptRSA(plainText, rePublicKey);
String decryptedRe = RSAUtil.decryptRSA(encryptedRe, privateKey);
Assert.assertEquals(plainText, decryptedRe);
// base64 암호화한 String 에서 Private Key 를 다시생성한후 복호화 테스트를 진행
PrivateKey privateKeyRe = RSAUtil.getPrivateKeyFromBase64Encrypted(base64PrivateKey);
String decryptedReRe = RSAUtil.decryptRSA(encryptedRe, privateKeyRe);
Assert.assertEquals(decrypted, decryptedReRe);
}
}
Client 에서 public key로 암호화한 암호문을 보내고
(String encrypted = RSAUtil.encryptRSA(plainText, publicKey) )
Server 에서 private key로 암호문을 해독하여
(String decrypted = RSAUtil.decryptRSA(encrypted, privateKey) )
검증하도록 구현가능하다.
'Study' 카테고리의 다른 글
SQL vs NOSQL (관계형데이터베이스 비 관계형데이터베이스) (2) | 2020.07.08 |
---|---|
(MessageQueue (MQ))란? 왜사용하게 되었을까? (10) | 2020.06.30 |
(Java) 참조 유형 (Strong Reference/ Soft Reference/ Weak Reference/ Phantom References) (0) | 2020.04.22 |
(Java) JVM 메모리 구조 및 변수 적재 위치 (2) | 2020.04.17 |
JPA란? 왜사용하나요? 짧은 답변 (0) | 2020.03.30 |
댓글