暗号で使用できるビット数を調べる
Javaは標準では「強力ではあっても制限付きの暗号」という微妙な表現の暗号しか使うことができません。これはブロック暗号なら128ビットまで許可、といったビット数による輸出(輸入?)規制に合わせるために、使用可能なビット数を制限するという意味のようです。
もう少し強力な暗号が使いたいなぁという場合には、Javaのページなどからファイルをダウンロードして、JREにあるファイルと入れ替える*1と解除することができます。
ただデフォルトが規制された状態であるため、使う前には制限が解除されているかどうかを確認する必要があります。試しに大きめのサイズにしてExceptionが発生したら少なめにする、というアホな方法を考えたのですが、そんなことをしなくても確認できる手段がちゃんと用意されていました。
public void dumpCipherAlgorithms() { // 暗号化に使用可能なアルゴリズムを取得 Set<String> algorithmSet = Security.getAlgorithms("Cipher"); for(String algorithm : algorithmSet) { // アルゴリズムごとの最大ビット長を取得 int maxLength = Cipher.getMaxAllowedKeyLength(algorithm); System.out.println(String.format("%-24s: %d", algorithm, maxLength); } }
Cipher.getMaxAllowedKeyLength()というそのままなメソッドです。これを実行した結果はこんな感じです。
BLOWFISH : 128 ARCFOUR : 128 PBEWITHMD5ANDDES : 128 RC2 : 128 RSA : 2147483647 PBEWITHMD5ANDTRIPLEDES : 128 PBEWITHSHA1ANDDESEDE : 128 DESEDE : 2147483647 AESWRAP : 128 AES : 128 DES : 64 DESEDEWRAP : 128 RSA/ECB/PKCS1PADDING : 2147483647 PBEWITHSHA1ANDRC2_40 : 128
概ね規制対象かどうかの判断基準である128ビットになっていることが分かります。一部に2147483647という不思議な数字がありますが、これはInteger.MAX_VALUEの値でビット数が無制限の場合はこの値になるようです。
当然ながら無制限といっても、アルゴリズム的にサポートされているビット数までしか使うことはできません。だったらその最大値を返してほしい気もするのですが、メソッド名がMaxAllowedなのでこういう仕様なのでしょうね。
あとなぜかRSAが最初から無制限になっています。昔は2048ビットまでだった記憶があるのですが、Java 6から無制限に変わっていたようです。
ちなみに制限を解除した場合は、こんな感じにすべてのアルゴリズムで制限がなくなります。
BLOWFISH : 2147483647 ARCFOUR : 2147483647 PBEWITHMD5ANDDES : 2147483647 RC2 : 2147483647 RSA : 2147483647 PBEWITHMD5ANDTRIPLEDES : 2147483647 PBEWITHSHA1ANDDESEDE : 2147483647 DESEDE : 2147483647 AESWRAP : 2147483647 AES : 2147483647 DES : 2147483647 DESEDEWRAP : 2147483647 RSA/ECB/PKCS1PADDING : 2147483647 PBEWITHSHA1ANDRC2_40 : 2147483647