AES 暗号化

こんどは、AES 暗号化、前回同様に、、、

import java.security.Key;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
 * AES/CBC/PKCS5Padding 暗号化、プロバイダは、SunJCE
 */

public abstract class AbstractAESCipher{
   /** 128-bit;16byte の鍵 */
   public abstract byte getKey();

   /** 初期化ベクトル 16byte */
   public abstract byte
 getInitVector();

   private Key skey;
   private AlgorithmParameterSpec ivParamSpec;

   public AbstractAESCipher(){
      byte keybyte = this.getKey();
      if (keybyte.length != 16){
         throw new RuntimeException("getKey() return length must be 128bit.");
      }
      this.skey = new SecretKeySpec(keybyte,"AES");
      byte
 vector = this.getInitVector();
      if (vector.length != 16){
         throw new RuntimeException("getInitVector() return length must be 16byte.");
      }
      this.ivParamSpec = new IvParameterSpec(vector);
   }


   /**
    * 暗号化
    * @param text クリアテキスト
    * @return 暗号化された文字列 byte
    */

   public final byte encrypt(String text){
      try{
      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding","SunJCE");
      cipher.init(Cipher.ENCRYPT_MODE,this.skey,this.ivParamSpec);
      byte iv = cipher.getIV();
      byte
 enc = cipher.doFinal(text.getBytes());
      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);
      }
   }

   /**
    * 複合化
    * @param data 暗号化されたデータ
    * @return 複合した文字列
    */

   public final String decrypt(byte data){
      try {
      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding","SunJCE");
      cipher.init(Cipher.DECRYPT_MODE,this.skey,this.ivParamSpec);
      int blocksize = cipher.getBlockSize();
      return new String(cipher.doFinal(data,blocksize,data.length - blocksize));
      }catch(Exception e){
         throw new RuntimeException(e);
      }
   }

   /**
    * アルゴリズム javax.crypto.spec.SecretKeySpec キー
    * @return java.security.Key
    */

   public Key getSecretKeySpec(){
      return this.skey;
   }
   /**
    * @return AlgorithmParameterSpec
    */

   public AlgorithmParameterSpec getAlgorithmParameterSpec(){
      return this.ivParamSpec;
   }
}

これを継承して、


public class MyAESCipher extends AbstractAESCipher{
   @Override
   public byte getKey(){
      return new byte
{
 (byte)0x12,(byte)0x53,(byte)0x2a,(byte)0xfc
,(byte)0x2e,(byte)0xc8,(byte)0x76,(byte)0x6d
,(byte)0x72,(byte)0x00,(byte)0x5f,(byte)0x3c
,(byte)0x08,(byte)0x82,(byte)0x1a,(byte)0x80
      };
   }
   @Override
   public byte getInitVector(){
      return new byte
{
 (byte)0xF8,(byte)0x75,(byte)0x09,(byte)0x13
,(byte)0x86,(byte)0xA4,(byte)0xC1,(byte)0x26
,(byte)0x50,(byte)0xA2,(byte)0x2d,(byte)0x7a
,(byte)0x00,(byte)0xe4,(byte)0x12,(byte)0x12
      };
   }
}

テストプログラム、

   MyAESCipher cipher = new MyAESCipher();

   String target = "abcd 1234 _!@/#$% ~あいうABC";
   System.out.println(target);

   byte[] encdata = cipher.encrypt(target);
  // Base64 は、import org.apache.commons.codec.binary.Base64;
  String encstr = new String(Base64.encodeBase64(encdata));


   System.out.println("\n暗号化!!");
   System.out.println(encstr );
   System.out.println("length = "+encdata.length);

   String decString = cipher.decrypt(Base64.decodeBase64(encstr.getBytes()));

   System.out.println("\n複合化!!");
   System.out.println(decString);
   System.out.println(target.equals(decString) ? "\nOK" : "\nNG");

実行結果は、

abcd 1234 _!@/#$% ~あいうABC

暗号化!!
+HUJE4akwSZQoi16AOQSEmYTQG054Z0zlG12az4247JapOHEItWyGlLmDuMkXUpTH4jd4kd/euF8ffxJ2upO8g==
length = 64

複合化!!
abcd 1234 _!@/#$% ~あいうABC

OK