import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; public class Encryptor { /** エリアス名 */ private static final String ALIAS_NAME = "aesKey"; /** 暗号化キーを保存するファイル */ private File keyFile; /** 認証用パスワード */ private static final char[] KEY_PASSWORD = {'p', 'a', 's', 's', 'w', 'o', 'r', 'd'}; /** IV */ private static final IvParameterSpec IV = new IvParameterSpec("1234567812345678".getBytes()); /** keyStore */ private KeyStore jceks; public static void main( String[] args) throws IOException { Encryptor encryptor = new Encryptor(new File(".keyFile")); /* 初期化(keyStoreをロード */ encryptor.initialize(); /* 鍵を保存 */ encryptor.saveKey(); /* 暗号化 */ byte[] encrypt = encryptor.encrypt("これを暗号化するよ"); /* 復号化 */ byte[] decrypt = encryptor.decrypt(encrypt); System.out.println("new String(decrypt) = " + new String(decrypt)); } public Encryptor(File keyFile) { this.keyFile = keyFile; } private void initialize() throws IOException { FileInputStream inputStream = null; if (keyFile.exists()) { inputStream = new FileInputStream(keyFile); } KeyStore jceks; try { jceks = KeyStore.getInstance("JCEKS"); jceks.load(inputStream, KEY_PASSWORD); } catch (CertificateException | NoSuchAlgorithmException | KeyStoreException | IOException e) { throw new IllegalStateException("failed to load key store.", e); } finally { if (inputStream != null) { inputStream.close(); } } this.jceks = jceks; } private byte[] encrypt(String text) { try { Key key = loadKey(ALIAS_NAME); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key, IV); return cipher.doFinal(text.getBytes()); } catch (IOException | KeyStoreException | NoSuchAlgorithmException | CertificateException | UnrecoverableKeyException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) { throw new IllegalStateException("failed to encrypt.", e); } } private byte[] decrypt(byte[] encryptData) { try { Key key = loadKey(ALIAS_NAME); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, key, IV); return cipher.doFinal(encryptData); } catch (IOException | KeyStoreException | NoSuchAlgorithmException | CertificateException | UnrecoverableKeyException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) { throw new IllegalStateException("failed to encrypt.", e); } } private Key loadKey(String key) throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException { return jceks.getKey(ALIAS_NAME, KEY_PASSWORD); } private void saveKey() throws IOException { try { if (!jceks.isKeyEntry(ALIAS_NAME)) { // 任意のキーを生成してkeyStoreにセット KeyGenerator aes = KeyGenerator.getInstance("AES"); jceks.setKeyEntry(ALIAS_NAME, aes.generateKey(), KEY_PASSWORD, null); } // keyStoreファイルを保存 try (FileOutputStream outputStream = new FileOutputStream(keyFile)) { jceks.store(outputStream, KEY_PASSWORD); } } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException e) { throw new IllegalStateException("failed to store key.", e); } } }
2012年3月24日土曜日
JavaでAES暗号
KeyStoreで鍵を管理して、その鍵をつかって暗号化と復号化をするコード。