0
0

More than 1 year has passed since last update.

【Java】3DESとBASE64での暗号化/復号化 実装メモ

Posted at

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

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0