こんどは、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