Java Tips:手軽に暗号化・復号化するには?JAVA Developer

J2SE 1.4からはJCEやJAASなどの各種セキュリティパッケージが標準で組み込まれ,暗号化や復号化などは簡単に行えるようになりました。ここでは秘密鍵を用いた手軽な暗号化を紹介します。

» 2004年07月01日 06時18分 公開
[JAVA Developer]

暗号化は気を遣う

 プログラムで暗号を使いたいとき,自前で実装するのは非常に気を遣います。なぜなら,バグがあったときにデータが復元できなくなるため,慎重に実装したうえで十分にテストしておく必要があるからです。

 前述のとおり,J2SE 1.4ではセキュリティパッケージが多数組み込まれたため,これらのロジックを自前で記述する必要性は大幅に低下しました。そこで,ここで簡単な利用法を紹介します。

 暗号化・復号化は一般にバイト列を暗号化してバイト列にする,というのが標準的な使い方です。しかし,ここでは動作を確認しやすくする目的で,「テキスト→暗号バイト列→テキスト」という流れにしましょう。

手軽に暗号化

 暗号関係のクラスは,統一的なインタフェースで暗号アルゴリズムだけを切り替えて使えるようになっています。ここでの暗号化には,Blowfishアルゴリズムを使うことにします。リスト1が秘密鍵と文字列を受け取って,暗号化を施して,暗号バイト列を返すメソッドのサンプルです。

[リスト1] 暗号化する例
private static byte[]   encrypt(String key, String text)
        throws javax.crypto.IllegalBlockSizeException,
            java.security.InvalidKeyException,
            java.security.NoSuchAlgorithmException,
            java.io.UnsupportedEncodingException,
            javax.crypto.BadPaddingException,
            javax.crypto.NoSuchPaddingException
{
    javax.crypto.spec.SecretKeySpec sksSpec = 
        new javax.crypto.spec.SecretKeySpec(key.getBytes(), "Blowfish");
    javax.crypto.Cipher cipher = 
        javax.crypto.Cipher.getInstance("Blowfish");
    cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, sksSpec);
    byte[] encrypted = cipher.doFinal(text.getBytes());
    return encrypted;
}

 今回のサンプルは,すべて完全修飾クラス名(FQCN)で記述してあります。リストからわかるように,javax.cryptoパッケージとjavax.crypto.specパッケージを利用します。多くの例外がthrowsされるため煩雑に見えますが,処理自体は簡単なものです。

 重要な行は「cipher.init」から2行です。データをdoFinalメソッドに一括して渡しているので,とても簡単になっています。

 秘密鍵SecretKeySpecを作る行とcipherを作る行とで,暗号化アルゴリズム「Blowfish」を指定していることがわかると思います。これらのアルゴリズム名は大文字・小文字を区別しません。

手軽に復号化

 同様に,複合化の例はリスト2のようになります。

[リスト2] 復号化する例
private static String   decrypt(String key, byte[] encrypted)
        throws javax.crypto.IllegalBlockSizeException,
            java.security.InvalidKeyException,
            java.security.NoSuchAlgorithmException,
            java.io.UnsupportedEncodingException,
            javax.crypto.BadPaddingException,
            javax.crypto.NoSuchPaddingException
{
    javax.crypto.spec.SecretKeySpec sksSpec = 
        new javax.crypto.spec.SecretKeySpec(key.getBytes(), "Blowfish");
    javax.crypto.Cipher cipher = 
        javax.crypto.Cipher.getInstance("Blowfish");
    cipher.init(javax.crypto.Cipher.DECRYPT_MODE, sksSpec);
    byte[] decrypted = cipher.doFinal(encrypted);
    return new String(decrypted);
}

 この例でも,重要な行は「cipher.init」から2行です。この例では,最終的に複合化したデータは,無条件でStringに変換して返します。

 今回は,利用するアルゴリズムとしてBlowfishを利用しました。前述のようにこれらのAPIはBlowfish以外にも「DES」などいくつかあります。

 SecretKeySpecに与える暗号化アルゴリズム名に関してSecretKeySpecのJavadocを読んでいると,「Java暗号化アーキテクチャAPIの仕様およびリファレンスの付録Aを参照」と書いてあります。しかし,実際には「Java暗号化拡張機能(JCE)リファレンスガイドの付録A」のほうが適切でしょう。インターネット上では,次のリンクで参照できます。

 Java暗号化拡張機能(JCE)リファレンスガイドの付録A

 JAVA Developerより毎週Java Tipsをお届けしましょう。バックナンバーもよろしく。

Copyright(C) 2010 SOFTBANK Creative Inc. All Right Reserved.

注目のテーマ