AES暗号化と複合化

CipherInputStream と、CipherOutputStream を合わせて、AES暗号化複合化の為のクラスをまとめる。

import java.io.InputStream;
import java.io.OutputStream;
import java.security.Key;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
 * AESCriptor
 */

public final class AESCriptor{
   private Key secretKey;
   private AlgorithmParameterSpec ivParamSpec;

   /**
    * Constructor
    * @param key 256-bit or 128-bit
    * @param iv 16byte Initialize Vector
    */

   public AESCriptor(byte key,byte iv){
      secretKey = new SecretKeySpec(key,"AES");
      ivParamSpec = new IvParameterSpec(iv);
   }
   public byte encrypt(byte data){
      try{
         Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
         cipher.init(Cipher.ENCRYPT_MODE,this.secretKey,this.ivParamSpec);
         byte iv = cipher.getIV();
         byte
 enc = cipher.doFinal(data);
         byte bs = new byte[iv.length + enc.length];
         System.arraycopy(iv,0,bs,0,iv.length);
         System.arraycopy(enc,0,bs,iv.length,enc.length);
         return bs;
      }catch(Exception e){
         throw new RuntimeException(e);
      }
   }
   public byte
 decrypt(byte data){
      try{
         Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
         cipher.init(Cipher.DECRYPT_MODE,this.secretKey,this.ivParamSpec);
         int blocksize = cipher.getBlockSize();
         return cipher.doFinal(data,blocksize,data.length - blocksize);
      }catch(Exception e){
         throw new RuntimeException(e);
      }
   }
   public int encryptSize(byte
 data){
      try{
         Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
         cipher.init(Cipher.ENCRYPT_MODE,this.secretKey,this.ivParamSpec);
         byte iv = cipher.getIV();
         byte
 enc = cipher.doFinal(data);
         return iv.length + enc.length;
      }catch(Exception e){
         throw new RuntimeException(e);
      }
   }
   public CipherOutputStream getCipherOutputStream(OutputStream outstream){
      try{
         Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
         cipher.init(Cipher.ENCRYPT_MODE,this.secretKey,this.ivParamSpec);
         CipherOutputStream cout = new CipherOutputStream(outstream, cipher);
         outstream.write(cipher.getIV());
         return cout;
      }catch(Exception e){
         throw new RuntimeException(e);
      }
   }
   public CipherInputStream getCipherInputStream(InputStream instream){

      try{
         Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
         cipher.init(Cipher.DECRYPT_MODE,this.secretKey,this.ivParamSpec);
         CipherInputStream cin =  new CipherInputStream(instream, cipher);
         int blocksize = cipher.getBlockSize();
         for(int i=0;i < blocksize;i++) cin.read();

         return cin;
      }catch(Exception e){
         throw new RuntimeException(e);
      }
   }
}


AES 256 bit を使うには、JCE ポリシーファイルを ORACLEのページからダウンロード
Java7 なら、UnlimitedJCEPolicyJDK7.zip
Java6 なら、jce_policy-6.zip

いずれも、解凍して以下のファイルを
  local_policy.jare
  US_export_policy.jar

を、JREが探すライブラリの下、$JRE_HOME/lib/security の下に置く。
(上書きする)