技術者ブログ
クラウド型WAF「Scutum(スキュータム)」の開発者/エンジニアによるブログです。
金床“Kanatoko”をはじめとする株式会社ビットフォレストの技術チームが、“WAFを支える技術”をテーマに幅広く、不定期に更新中!

Tomcat 8.0.21でサーバ側SSL暗号スイート選択が可能に
はじめに
以前のエントリに書いたように、Java7以前では、SSL通信の際にサーバソケット側で暗号スイートを決定することができず、どうしてもやりたい場合にはJSSEのソースコードを書き換える必要がありました。しかし昨今、SSLに関連する多くの脆弱性や問題が相次いで見つかるようになっており、サーバ側でも暗号スイートをコントロールしたいというニーズは高まっていると思います。Java8ではJSSEにおいてサーバ側暗号スイート選択の機能が実装され、またTomcatでも8.0.21においてこれが可能になりました。
Java8での変更
Java8での変更に関するOracleの一次情報はこちらです。
SSLParameters.setUseCipherSuitesOrder(true)
とすることで、サーバ側の設定が優先されて暗号スイートが選択されるようになります。
もっともイメージしやすいユースケースとして、クライアントがやや強度の弱い暗号スイートをリストの先頭に持っているが、サーバから見て好ましい、より強度の高い暗号スイートも同時にリスト中に存在する場合に、それを使うことが可能になります。
Tomcatの対応
Tomcatは8.0.21でこのJava8の機能を活かせるようになりました。詳しくはこちらのページのuseServerCipherSuitesOrderの項目を参照ください。
Tomcat8.0.21はJava7でも動作しますが、このときは(当然ですが)useServerCipherSuitesOrderは使えず、クライアント側の暗号スイートリストが優先されます。
筆者は個人的にTomcatが「Java7で動作しているのか、Java8で動作しているのか」をどのように判別しているのかについて興味があったので、このuseServerCipherSuitesOrderの処理を行う部分についてソースコードを当たってみました。該当するのは次の箇所(799行目)です。
// This method is only available in Java 8+ // Check to see if the method exists, and then call it. Method m = SSLParameters.class.getMethod("setUseCipherSuitesOrder", Boolean.TYPE);m.invoke(sslParameters, Boolean.valueOf(useServerCipherSuitesOrder));
リフレクション(Javaにおけるメタプログラミング)を利用してメソッドを呼び出しています。仮にJava7の場合にはメソッドが存在しないので例外が送出されますが、それはcatchされて処理されるようになっています。つまりJavaのバージョンを取得して判別するわけではなく、あくまでも実装されているかどうかで判断していることになります。なかなかスマートなやり方だと思いました。
まとめ
今回はJava8とTomcat8.0.21の組み合わせによってサーバ側で暗号スイートが選択できるようになった件について、簡単にまとめました。