AES128暗号化 - Java編 -
先日iPhone(というかObjective-C)でのAES128暗号化について触れましたが、今回はJava編です。未確認ですが、おそらくAndroidでも動きます。
/* * $ javac CryptAES.java * $ java CryptAES <secret_key> <iv> <message> */ import java.security.spec.AlgorithmParameterSpec; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.IvParameterSpec; class CryptAES { static final String cipher_type = "AES/CBC/PKCS5Padding"; public static void main(String[] args) { String key = args[0]; String iv = args[1]; String data = args[2]; byte[] enc = encode(key, iv, data.getBytes()); byte[] dec = decode(key, iv, enc); for (int i = 0; i < enc.length; i++) { System.out.printf("%02x", enc[i]); } System.out.println(); System.out.println(new String(dec)); } public static byte[] encode(String skey, String iv, byte[] data) { return process(Cipher.ENCRYPT_MODE, skey, iv, data); } public static byte[] decode(String skey, String iv, byte[] data) { return process(Cipher.DECRYPT_MODE, skey, iv, data); } private static byte[] process(int mode, String skey, String iv, byte[] data) { SecretKeySpec key = new SecretKeySpec(skey.getBytes(), "AES"); AlgorithmParameterSpec param = new IvParameterSpec(iv.getBytes()); try { Cipher cipher = Cipher.getInstance(cipher_type); cipher.init(mode, key, param); return cipher.doFinal(data); } catch (Exception e) { System.err.println(e.getMessage()); throw new RuntimeException(e); } } }
今回はivは指定のものを使うようにしてありますが、特に指定がなければ自動で生成されますし、そのivをあとから取り出すことももちろん可能です。
パディング方式に関しては外部ライブラリをいれない限りはPKCS7が使えません。ただし、デフォルトで使えるPKCS5は7と互換性が(ほぼ)あるため、特に問題が起きることはないでしょう(逆にPKCS7のライブラリがバグってるという話もあるので、無理にPKCS7にしようとすると本末転倒な結果になりかねません)。
それから、128bitの指定などは特にしていないのですが、secret keyやivの長さ(どちらも16バイト)から自動で判別しているのだと思います。secret keyの長さを変えれば自動で256bitになったりするのでしょうか(要検証)。
Javaは普段使ってないので、もしマズいところがあればご指摘頂けるとありがたいです。