3DESとは
3DESまたはTripleDesとはDES暗号化アルゴリズムを各データブロックに3回適用する対称鍵ブロック暗号です。
今回はJavaでの3DESによる暗号化/復号化、BASE64でのエンコード/デコードの処理を実装したので実装メモとして記載します。
1.秘密鍵の生成
キーの生成
private static final byte[] SECRET_KEY = "6ydjai8dnfy4ud9d8dud7dud".getBytes();//24-byte
24バイトのキーを使用します。
キーをSecretKeySpecでラップし、アルゴリズムと組み合わせる
private final String CRYPT_ALGORITHM = "DESede";
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, CRYPT_ALGORITHM);
今回はDESedeを使用していますが、Javaセキュリティ標準アルゴリズムの中から適切なものを使用してください。
2.初期化ベクトルの生成
初期化ベクトルの生成乱数と文字の8バイト配列を使用します。
private static final byte[] IV = "ud8dks7s".getBytes();//8-byte
8バイト配列を使用します。
IvParameterSpecクラスでラップ
IvParameterSpec ivSpec = new IvParameterSpec(IV);
3.暗号化
使用する文字列を定義
String srcText = "DesedeTest ";
CBC/パディングなしで3DESアルゴリズムを使用するので、最後の8バイトブロックに対し、補完文字列が必要です。
DeseseTe
st□□□□□□
※□=半角スペースで補完しています。
暗号化モード、秘密鍵、および以前に生成した初期化ベクトルで初期化されたCipherオブジェクトを生成
private static final String PADDING = "DESede/CBC/NoPadding";
Cipher cipher = Cipher.getInstance(PADDING);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
暗号化時は、ENCRYPT_MODE
を使用します。
暗号化
byte[] encrypted = cipher.doFinal(srcText.getBytes());
Cipherを使用すると、 doFinalメソッドを実行してメッセージを暗号化できます。
これはバイト配列でのみ機能するため、最初に文字列を変換する必要があります。
BASE64でエンコード
byte[] base64EncodedValue = Base64.getEncoder().encode(encrypted);
java.util.Base64
のEncoderでエンコードすることでBASE64でエンコードされたバイト配列を取得できます。
new String(base64EncodedValue)
とすることで、文字列に変換できます。
4.復号化
BASE64でデコード
byte[] base64DecodedValue = Base64.getDecoder().decode(base64EncodedText);
復号化用のCipherオブジェクトを生成
Cipher cipher = Cipher.getInstance(PADDING);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec);
復号化時は、DECRYPT_MODE
を使用します。
復号化
byte[] decrypted = cipher.doFinal(base64DecodedValue);
コード
package desedeSample;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* Encrypt/Decrypt by using Triple-DES
*
* @author ueD
*/
public class DesedeCrypter {
private static final String CRYPT_ALGORITHM = "DESede";
private static final String PADDING = "DESede/CBC/NoPadding";
private static final byte[] SECRET_KEY = "6ydjai8dnfy4ud9d8dud7dud".getBytes();//24-byte
private static final byte[] IV = "ud8dks7s".getBytes();//8-byte
public static void main(String[] args) throws Exception {
// 8バイトブロックに対し半角スペースで補完
String srcText = "DesedeTest ";
System.out.println("srcText: " + srcText);
DesedeCrypter crypter = new DesedeCrypter();
// 秘密鍵
SecretKeySpec secretKeySpec = new SecretKeySpec(SECRET_KEY, CRYPT_ALGORITHM);
// 初期化ベクトル
IvParameterSpec ivSpec = new IvParameterSpec(IV);
// 暗号化処理
byte[] encrypted = crypter.encrypt(srcText, secretKeySpec, ivSpec);
System.out.println("3DES: " + new String(encrypted));
//BASE64でエンコード
String base64EncodedText = new String(Base64.getEncoder().encode(encrypted));
System.out.println("BASE64エンコード: " + base64EncodedText);
// 復号化処理
// BASE64でデコード
String base64DecodedText = new String(Base64.getDecoder().decode(base64EncodedText));
System.out.println("3DES: " + base64DecodedText);
byte[] decrypted = crypter.decrypt(Base64.getDecoder().decode(base64EncodedText), secretKeySpec, ivSpec);
System.out.println("srcText復号化: " + new String(decrypted));
}
/**
* 3DESによる暗号化を行う
* @param value
* @return
* @throws Exception
*/
public byte[] encrypt(String value, SecretKeySpec secretKeySpec, IvParameterSpec ivSpec) throws Exception {
try {
Cipher cipher = Cipher.getInstance(PADDING);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
// 暗号化
byte[] encrypted = cipher.doFinal(value.getBytes());
return encrypted;
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
/**
* 3DESによる復号化を行う
* @param value
* @return
* @throws Exception
*/
public byte[] decrypt(byte[] value, SecretKeySpec secretKeySpec, IvParameterSpec ivSpec) throws Exception {
try {
Cipher cipher = Cipher.getInstance(PADDING);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec);
byte[] decrypted = cipher.doFinal(value);
return decrypted;
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}
実行結果
srcText: DesedeTest
3DES: P��-�����'�~�A
BASE64エンコード: UOQACy3u+qz0FOYnnn6OQQ==
3DES: P��-�����'�~�A
srcText復号化: DesedeTest
参考
git