Java SE 7のSecurity Enhancementsには

CertPath Algorithm Disabling
Weak cryptographic algorithms can now be disabled. For example, the MD2 digest algorithm is no longer considered secure. The Java SE 7 release provides a mechanism for denying the use of specific algorithms in certification path processing and TLS handshaking. See Appendix D: Disabling Cryptographic Algorithms in Java PKI Programmer's Guide and Disabled Cryptographic Algorithms in Java Secure Socket Extension (JSSE) Reference Guide for more information.
と書いてあります。なるなる。証明書の検証において弱い暗号アルゴリズムを使わないように設定することができ、これはSSL/TLSの場合でも同様に設定できるようです。今日はこのアルゴリズム無効化について説明したいと思います。

プロパティファイル java.security の違い

Java SE 6 と7では若干$JRE_HOME/lib/security/java.securityのファイルの内容が違うんですが、 大きく追加されているのは3点あります。

  • Policy for failed Kerberos KDC lookups - Kerberosの設定
  • Algorithm restrictions for certification path (CertPath) processing - (証明書の)認証パス検証処理のアルゴリズム制限
  • Algorithm restrictions for Secure Socket Layer/Transport Layer Security (SSL/TLS) processing - SSL/TLS処理のアルゴリズム制限
一般の証明書検証とSSL/TLSでの証明書検証とで分けてアルゴリズムに制限をかけることができるようです。 ちなみに一般の証明書検証ではデフォルトは
jdk.certpath.disabledAlgorithms=MD2
になっており、MD2アルゴリズムは無効になるよう設定されています。SSL/TLSでは
jdk.tls.disabledAlgorithms
のプロパティで設定するようになっていますが、SSL/TLSにおいては無効設定は無いようです。

アルゴリズムの無効化の指定方法

指定するのは署名アルゴリズムではなく、ハッシュアルゴリズムと公開鍵暗号のアルゴリズムで、 公開鍵暗号のアルゴリズムについては、鍵長を指定できます。以下に幾つか設定の例を示します。
# MD2を無効化(デフォルト)
jdk.certpath.disabledAlgorithms=MD2
# MD2, SHA1, DSA, ECDSAを無効化
jdk.certpath.disabledAlgorithms=MD2, SHA1, DSA, ECDSA
# MD2, SHA1 を無効とし、鍵長2048bit未満のRSAを無効
jdk.certpath.disabledAlgorithms=MD2, SHA1, RSA keySize < 2048
RIPEMD-160等のSun(Oracle)提供の暗号アルゴリズムにないものを指定できるのかは 気になるところです。時間が取れたら見てみます。

プログラムの中でアルゴリズム制限を指定する

上記のようにプロパティファイルで指定することもできますが、 プログラムの中でも動的に指定することも可能です。

import java.security.Security;
・・・
Security.setProperty("jdk.certpath.disabledAlgorithms", "MD2, MD5, DSA");

で、実際に使ってみた

試しにRSAの鍵長を可変にして、どうなるか試してみました。

# jdk.certpath.disabledAlgorithms=RSA keySize < 1024 -- RSA1024bit未満を禁止
→検証成功
# jdk.certpath.disabledAlgorithms=RSA keySize < 2048 -- RSA2048bit未満を禁止
→unable to find valid certification path to requested target
う〜ん、確かにプロパティの変更によって検証結果は変わりますが、 例外のメッセージは全くアルゴリズム理由でそうなったのか わからないようになっちゃってますね。

仕方ないのでデバックメッセージを表示するようにして (java -Djava.security.debug=all) メッセージを見てみるとアルゴリズムを禁止した場合と鍵長を制限した 場合とでメッセージが異なるみたいです。

# jdk.certpath.disabledAlgorithms=RSA -- RSAを禁止してみた場合
algorithm check failed: SHA1withRSA disabled
# jdk.certpath.disabledAlgorithms=RSA keySize < 2048 -- RSA2048bit未満を禁止
algorihtm constraints check failed

暗号アルゴリズムの危殆化情報の管理と自動処理

暗号アルゴリズムは時代の変遷とともに脆弱になり、推奨されない暗号の鍵長もまた 変わっていきます。特に過去の電子署名ファイルや暗号化されたファイルで 使われている暗号アルゴリズムが当時大丈夫だったのかは気になるところです。 「 RFC 5698 Data Structure for the Security Suitability of Cryptographic Algorithms (DSSC)」というデータフォーマットがありますが、これは、 は、 どの暗号アルゴリズムや鍵長が何時の時代に、どのくらいの期間までは安全とされていたかを規定することができるデータフォーマットです。

現在、DES、MD5、SHA1、鍵長の短いRSAなど暗号アルゴリズムの危殆化が話題になっていますが、どのアルゴリズムが何年から何年頃までは使い物になったのかをNIST、CRYPTRECなど暗号アルゴリズムの公的な評価機関がDSSCのような電子データの形式として公開、発行して頂けると、このデータを検証ポリシーとして使用し、過去のあるデータが「当時安全とされていた暗号アルゴリズム(や鍵長)」を使っていたかを自動的に判定できるようになります。

DSSCの内容により自動的にjdk.certpath.disabledAlgorithmsに反映させて検証するなんてこともできますね。

おわりに

今日はJava SE 7で新たに提供されることになった証明書検証における弱い暗号アルゴリズムの制限機能について紹介しました。 これまでに、暗号スイートのレベルで制限することはできましたが、ハッシュや公開鍵暗号アルゴリズム、鍵長のレベルでミドルウェアで制限が加えられる汎用の製品はJava SE 7が初めてなのではないかと思います。 SSL/TLSにも使えるので、そろそろ "jdk.tls.disabledAlgorithms=MD2" などとしてもいい頃ですよね。

やべやべ、会社は夏休みなんだけど明日から一週間休日出勤だ。風呂入って寝よう。ではでは。

関連記事>