共通鍵方式で 暗号化 / 復号化

まず鍵生成。アルゴリズムは "AES" とか "DESede" とか "Blowfish" とか。

public CryptKey generate(String keyAlgorithm, int keyLength) {
    try {
        KeyGenerator generator = KeyGenerator.getInstance(keyAlgorithm);
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
        if (seed != null) { random.setSeed(seed); }
        generator.init(keyLength, random);
        Key key = generator.generateKey();
…

このときの指定可能なアルゴリズムとキー長は、JDKデフォルト状態で以下の通り。
java.sun.comから制限解除ポリシーをDLしてくればもっと大きなキー長を指定可能。

AES - 128
DESede - 112, 168
Blowfish - 128


生成した共通鍵でに暗号化。
アルゴリズムモードがCBCのとき、復号化に必要なIVが暗号化時に生成される。
復号化ロジックに渡すためにデータの先頭に付与。

public byte[] encrypt(byte[] data) throws CryptException {
    try {
        keyConfig.load(); // 共通鍵のロード
        Key key = keyConfig.getKeyObject().getSecretKey();
        Cipher cipher = Cipher.getInstance(algorithm + "/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] iv = cipher.getIV();
        byte[] encrypted = cipher.doFinal(data);
        byte[] ret = new byte[4 + iv.length + encrypted.length];
        putByte(iv.length, ret); // int を頭4バイトに埋める
        System.arraycopy(iv, 0, ret, 4, iv.length);
        System.arraycopy(encrypted, 0, ret, 4+iv.length, encrypted.length);
        return ret;
    } catch (Exception e) {
        throw new CryptException(Crypter.class.getName() + ".encrypt", e);
    }
}

生成した共通鍵で復号化。
暗号化時に生成したIVを取り出して、復号化。

public byte[] decrypt(byte[] data) throws CryptException {
    try {
        int ivLength = toInt(data); // 頭4バイトをintにして返す
        keyConfig.load(); // 共通鍵のロード
        Key key = keyConfig.getKeyObject().getSecretKey();
        IvParameterSpec ivSpec = new IvParameterSpec(data, 4, ivLength);
        Cipher cipher = Cipher.getInstance(algorithm + "/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
        return cipher.doFinal(data, 4+ivLength, data.length-ivLength-4);
    } catch (Exception e) {
        throw new CryptException(Crypter.class.getName() + ".decrypt", e);
    }
}

IVを使わないパターンは Cipher.init() -> Cipher.doFinal()でおしまい。