公開鍵暗号方式(RSA)による暗号化、復号化を試してみる
前回PEM形式のファイルをBouncy Castleを利用して読み込めることが確認できたので、公開鍵暗号方式で暗号化、復号化を試してみようと思います。
ichiwork.hatenablog.com
公開鍵暗号方式では暗号化には公開鍵を利用し、復号化には秘密鍵を利用します。
サンプルソース
メイン
プログラムの流れとしては以下の流れです。
public class CriptoSample { private static final String ALGORITHM = "RSA"; public static void main(String[] args) { String org = "パパの頭にちょんまげがあったら、朝の挨拶おはようでござる"; KeyPair keypair = PEMUtil.pemToKeyPair("rs256.key.pkcs8", "rs256.pub.key"); try { System.out.println("元の文字列:" + org); String encrypted = CriptoUtil.cripto(org, keypair.getPublic(), ALGORITHM); System.out.println("暗号化後の文字列:" + encrypted); String decrypted = CriptoUtil.decrypt(encrypted, keypair.getPrivate(), ALGORITHM); System.out.println("複合化後の文字列:" + decrypted); } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException e) { e.printStackTrace(); } } }
PEMファイルから公開鍵、秘密鍵を生成するユーティリティークラス
Bouncy Castleを利用してPEMファイルから公開鍵と秘密鍵を生成しています。
public class PEMUtil { private PEMUtil() { }; private static final JcaPEMKeyConverter conv = new JcaPEMKeyConverter().setProvider(new BouncyCastleProvider()); public static PrivateKey pemToPrivateKey(String privateKeyFilePath) { PrivateKey privateKey = null; // PEM形式の秘密鍵ファイルからPrivateKeyを生成する try (PEMParser parser = new PEMParser( new InputStreamReader(ClassLoader.getSystemResourceAsStream(privateKeyFilePath)))) { Object obj = parser.readObject(); if (obj instanceof PrivateKeyInfo) { PrivateKeyInfo keyInfo = (PrivateKeyInfo) obj; privateKey = conv.getPrivateKey(keyInfo); } if (obj instanceof PEMKeyPair) { PEMKeyPair keyInfo = (PEMKeyPair) obj; privateKey = conv.getKeyPair(keyInfo).getPrivate(); } } catch (IOException e) { e.printStackTrace(); } return privateKey; } public static PublicKey pemToPublicKey(String publicKeyFilePath) { PublicKey publicKey = null; // PEM形式の公開鍵ファイルからPublicKeyを生成する try (PEMParser parser = new PEMParser( new InputStreamReader(ClassLoader.getSystemResourceAsStream(publicKeyFilePath)))) { Object obj = parser.readObject(); if (obj instanceof SubjectPublicKeyInfo) { SubjectPublicKeyInfo keyInfo = (SubjectPublicKeyInfo) obj; publicKey = conv.getPublicKey(keyInfo); } } catch (IOException e) { e.printStackTrace(); } return publicKey; } public static KeyPair pemToKeyPair(String privateKeyFilePath, String publicKeyFilePath) { PrivateKey privateKey = pemToPrivateKey(privateKeyFilePath); PublicKey publicKey = pemToPublicKey(publicKeyFilePath); KeyPair keyPair = null; // PrivateKey、PublicKeyからKeyPairを生成する if (publicKey != null && privateKey != null) { keyPair = new KeyPair(publicKey, privateKey); } return keyPair; } }
暗号化ユーティリティークラス
public class CriptoUtil { private CriptoUtil() { }; public static String cripto(String org, Key key, String algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { Cipher cipher; String dest = null; cipher = Cipher.getInstance(algorithm); cipher.init(Cipher.ENCRYPT_MODE, key); dest = new String(Base64.encode(cipher.doFinal(org.getBytes()))); return dest; } public static String decrypt(String encrypted, Key key, String algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { Cipher cipher; String org = null; cipher = Cipher.getInstance(algorithm); cipher.init(Cipher.DECRYPT_MODE, key); org = new String(cipher.doFinal(Base64.decode(encrypted.getBytes()))); return org; } }