【Java】シリアライズ、デシリアライズ、暗号化、base64エンコード

概要

シリアライズ

シリアライズとは、Javaオブジェクトからバイト配列に変換すること。
シリアライズするオブジェクトはSerializableインターフェースを実装する必要がある。

シリアライズ

シリアライズとは、シリアライズ化されたバイト配列からJavaオブジェクトに復元すること。

使用方法

オブジェクトをシリアライズ後、改ざん防止のための暗号化、見やすいようにbase64エンコードする
Formなどをweb画面上で持ち回るのに有効(hidden項目にセットして持ち回る)

シリアライズのフロー
 暗号化(Blowfish)→エンコード(base64)
・デシリアライズのフロー
 デコード(base64)→複合化(Blowfish)

    public String Sample() {
        // シリアライズ化するオブジェクトを作成
        OfferForm form= new OfferForm();
        form.setSeq("1");
        form.setName("テスト");
        try {
            // シリアライズ
            String serialForm = toSerialString(form);
            // デシリアライズ
            OfferForm restoreForm = (OfferForm)restoreObject(serialForm);
            String a = "";
        } catch (Exception e) {
            e.printStackTrace();
        }
        return;
    }

    /**
     * オブジェクトをシリアライズする
     *
     * @param object シリアライズするオブジェクト
     * @return シリアライズしたオブジェクト
     * @throws Exception
     */
    private String toSerialString(Object object) throws Exception{

        // Byte配列への出力を行うストリーム
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        // オブジェクトをストリーム(バイト配列)に変換する為のクラス
        ObjectOutputStream oos = new ObjectOutputStream(baos);

        // オブジェクトをバイト配列に変換
        oos.writeObject(object);
        oos.close();
        baos.close();

        // 暗号化
        byte[] byteCipher = null;
        byteCipher = cipher(baos.toByteArray());

        // Base64エンコード
        // ※文字コードの指定なし(文字コードはISO_8859_1になる)
        String encodedStr = Base64.getEncoder().encodeToString(byteCipher);
        // ※文字コードを指定する方法
        String encodedStr2 = new String(Base64.getEncoder().encode(byteCipher), StandardCharsets.UTF_8);

        return encodedStr;
    }
    /**
     * デシリアライズする
     *
     * @param serial シリアライズしたオブジェクト
     * @return デシリアライズしたオブジェクト
     * @throws Exception
     */
    private Object restoreObject(String serial) throws Exception {

        // Base64デコード
        byte[]decodedSerial = Base64.getDecoder().decode(serial);

        // 複合化
        byte[]decipherSerial = null;
        decipherSerial = decipher(decodedSerial);

        // ストリームを入力する
        ByteArrayInputStream bais = new ByteArrayInputStream(decipherSerial);

        // デシリアライズする為のクラスとストリーム入力を連結する
        ObjectInputStream os = new ObjectInputStream(bais);
        bais.close();
        os.close();

        // デシリアライズ
        Object object = os.readObject();

        return object;
    }

    /**
     * 暗号化する
     *
     * @param target 暗号化するバイト配列
     * @return 暗号化したバイト配列
     * @throws Exception
     */
    private byte[] cipher(byte[] target) throws Exception{
        Cipher cipher = null;
        byte[] result = null;

        // 暗号化の秘密鍵
        String key = "abcdefg";

        // 使用する暗号化アルゴリズム(ここではBlowfishを使用)
        String algorithm = "BLOWFISH";

        // 暗号化
        SecretKeySpec sksSpec = new SecretKeySpec(key.getBytes(), algorithm);
        cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.ENCRYPT_MODE, sksSpec);

        result = cipher.doFinal(target);

        return result;

    }
    /**
     * 複合化する
     *
     * @param target 複合化するバイト配列
     * @return 複合化したバイト配列
     * @throws Exception
     */
    private byte[] decipher(byte[] target) throws Exception {
        byte[] result;

        // 暗号化の秘密鍵
        String key = "abcdefg";

        // 使用する暗号化アルゴリズム(ここではBlowfishを使用)
        String algorithm = "BLOWFISH";

        // 複合化
        SecretKeySpec sksSpec = new SecretKeySpec(key.getBytes(), algorithm);
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.DECRYPT_MODE, sksSpec);

        result = cipher.doFinal(target);
        return result;
    }

シリアライズするオブジェクトは下記が必要
・Serializableインターフェースを実装
・serialVersionUIDを指定(Eclipse機能でランダムで作成できる)

public class OfferForm implements Serializable{

    private static final long serialVersionUID = -2576531688719632386L;

    private String seq;
    private String name;
    public String getSeq() {
        return seq;
    }
    public void setSeq(String seq) {
        this.seq = seq;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

Base64

Base64 とは、各種データを 64種類の半角英数字(0-9, A-Z, a-z, +, /, =)のみで表現される文字列に変換(エンコード)すること。

Base64 URLSafe

Base64 として表現される文字列に「+」「/」が含まれるためURLのパラメータに使用する場合はURLSafe でエンコードする必要がある。

    // エンコードの場合(getUrlEncoderを使用)
    String encodedStr = Base64.getUrlEncoder().encodeToString(byteCipher);

    // デコードの場合(getUrlDecoderを使用)
    byte[]decodedSerial = Base64.getUrlDecoder().decode(serial);