패딩 ( PKCS#1, OAEP )
대칭키와 다르게 암복호화 하는데 개인키, 공개키가 존재한다
JAVA에서 해당 키를 관리하기 위하여 KeyPair, PublicKey, PrivateKey, KeyPairGenerator ) 클래스를 제공한다
java.security.KeyPair
KeyPair는 공개키 개인 키 쌍을 캡슐화 한 클래스이다, doPublic(), doPrivate() 공개키, 개인키를 반환하는데 쓰인다
java.security.PublicKey
공개키의 인터페이스이다,
java.security.PrivateKey
개인키의 인터페이스이다
java.security.KeyPairGenerator
공개키 개인키 키쌍을 생성하는 방법을 제공한다
공개키 / 개인키 암복호화 예제
import javax.crypto.*;
import java.security.*;
import java.util.Base64;
public class Main {
public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
// 대칭키 발행
KeyGenerator keyGenerator = KeyGenerator.getInstance("Blowfish");
keyGenerator.init(128);
Key blowfishKey = keyGenerator.generateKey();
System.out.println("blowfishKey: "+ Base64.getEncoder().encodeToString(blowfishKey.getEncoded()));
// 공개키 발행
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
String base64PublicKeyStr = Base64.getEncoder().encodeToString(publicKey.getEncoded());
String base64PrivateKeyStr = Base64.getEncoder().encodeToString(privateKey.getEncoded());
System.out.println(base64PublicKeyStr.length()+"/ "+base64PublicKeyStr);
System.out.println(base64PrivateKeyStr.length()+"/ "+base64PrivateKeyStr);
Cipher sameKey = Cipher.getInstance("BlowFish/ECB/PKCS5Padding");
sameKey.init(Cipher.ENCRYPT_MODE, blowfishKey);
byte[] encryptedData = sameKey.doFinal("test".getBytes());
System.out.println("encrypted Data: "+Base64.getEncoder().encodeToString(encryptedData));
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encrypted = cipher.doFinal(Base64.getEncoder().encodeToString(encryptedData).getBytes());
StringBuilder sb = new StringBuilder();
for(byte i : encrypted){
sb.append(String.format("%02x", i));
}
System.out.println("publicKey Encrypted :"+Base64.getEncoder().encodeToString(encrypted));
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decode = cipher.doFinal(encrypted);
String decodeStr = new String(decode);
System.out.println("PrivateKe Decrypt: "+decodeStr);
sameKey.init(Cipher.DECRYPT_MODE, blowfishKey);
byte[] plainData = sameKey.doFinal(Base64.getDecoder().decode(decodeStr));
String plainDatStr = new String(plainData);
System.out.println("plainDatStr: "+plainDatStr);
}
}
blowfishKey: JoIODTTnNr2C/rq3m4Jj/Q==
216/ MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYsUnfTSpw3o6LyivqifcPJEvQ2xSGfHZv8T4Ps5XNGRs4IcSHX+oYg6wJHdxvqmKU577oDUJg4c8BgKe2XGdjSNSBAmtqJfCFzkU66XtTp0l+sRFBMHprF8CldsjW+brhAPRU2B/j8z7+VshGQWcBwGk7p+3nSXwIq7ZsXT1oUwIDAQAB
848/ MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJixSd9NKnDejovKK+qJ9w8kS9DbFIZ8dm/xPg+zlc0ZGzghxIdf6hiDrAkd3G+qYpTnvugNQmDhzwGAp7ZcZ2NI1IECa2ol8IXORTrpe1OnSX6xEUEwemsXwKV2yNb5uuEA9FTYH+PzPv5WyEZBZwHAaTun7edJfAirtmxdPWhTAgMBAAECgYBGZs/htomP+v2MdI3lGPGhuKGATdLb4z0Uhg2QXcP/CclkCyW7KT0dSnCiz3LYxZ2ofGWoRpzJYLP6RGCPk3FTPYb4ar6wp8lhcljn5sHgYgVR5f3X0zJevOufFbQBw1xTgXpJnoN11PqoApBwswu+sDQkmm/Lz1dsmXXf2h8yyQJBANo7tkUj8aglpZunsk5ugrjuqHKXZY0D6L7Vq+rvzInvKM8wKFsBYTQDjleQkOqrE7hd3IKjCrxx2EbDWU/4id0CQQCzHfTFidzdPQJgU9vJgROxFDkX41P9/l4XzHMvbOhzwouf5XFVloGF9ycggCAOn+xnvNiJa5QYxp3P1l5Td8/vAkASl0mkxDYe++4Kv5N6CQIL3RDuiiU1iSK3tx4pKnqDOaOBWvnlHs34D2F95iviQeaxKxXQ7zDH8u7YwGWIYYTlAkEAq5AU5KTxRYPrY8LO8YpOBz38lbHrwIxFKfxtk854NHDydfw5+yXG+D9MXef7TKbHtHGA4teFKdoMTIfjH4XSRwJAI7JYTpjiDvpGWtM5XJHQr551co3gS3Fp8mSZ4lxObfX4MwaLAm+dUVkiXrYhoA8dzz0r4ZDcqtqwnYuW5CINUA==
encrypted Data: JZJDyOeyL78=
publicKey Encrypted :VN4khcPzzTSFInzN//BR2+PnQB1HC2DhEaSoIuDxxHSZpz3hUAeIOJyWewJZfd7NqJEzgPRMPSNrFAWRq4LLYqEQZVtCJI/QpKOmSZnJ3NIrC2+XzjOUtYhzWqi9xFHKb9cACKgGhSY3sQXFE33QUOb55RiLmM7ttM2O3j6yIy4=
PrivateKe Decrypt: JZJDyOeyL78=
plainDatStr: test