JavaでSSL/TLS通信をしたい時に通常はJSSE(Java Secure Socket Extension)という仕組み使うんですが、これ使えば、実装色々切り替えたり、追加したりなんてことができます。Apache Tomcat(+Sun Java JSSE)だとCamellia系のCipherSuitesに対応してないそうで、何か対応してるもの、追加で対応できそうなものを調べてみました。
Sun Javaで使えるJSSEってあんまり選択肢がないのね
下の例のようにJSSEプロバイダ名を指定することによりJSSEを切り替えればいろんなSSLエンジンを試せるわけですが、
SSLContext ctx = SSLContext.getInstance(アルゴリズム名, プロバイダ名);Sun Javaで使えそうなJSSEの選択肢って少ないんだなぁってことが調査してみるとわかりました。Sun Javaで使えそうなのは標準品を含めて以下の3つぐらいしかなさそう。
SSLContext ctx = SSLContext.getInstance("SSL", "SunJSSE");
SSLContext ctx = SSLContext.getInstance("TLS", "HarmonyJSSE");
- Sun(Oracle) - SunJSSE
- RSA - RSA BSAFE SSL-J Toolkit
- IAIK - IAIK iSaSiLk Toolkit
なんか調べてみるとJSSEはJava VMに依存している方が多いんじゃないかって 感じがします。
- IBM Java - IBM JSSE
- GNU classpath - JESSIE (オープンソース)
- Apache Harmony - HarmonyJSSE (BouncyCastle JCEベース)
Apache HarmonyとTomcatを試してみる
Apahce HarmonyのSSL/TLSの機能というか、JSSEの機能は暗号ライブラリとしてBouncyCastle JCE Libraryを使用しており、SunJCEは使えません。 従ってHTTPSのためのSSLサーバー証明書と鍵はJKS形式はSun独自の形式なので使えなくてBouncyCastle JCEがサポートしている PKCS#12かBKS(BouncyCastle Key Store)形式を使う必要があります。 ただ、OpenSSLで生成したPKCS#12でやってみたところMacエラーだったりで読み込めず BKSを使うのがよいのかもしれません。 JKSからBKSへの変換ツールは「ここ」に置いてみたので使ってみてください。
conf/server.xml
ファイルにはこんな感じでkeystoreFile、keystorePass
、keystoreTypeを設定します。
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"あとは
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="conf/zzz.bks"
keystorePass="changeit"
keystoreType="BKS" />
bin/catalina.bat
に以下のようなパス設定をしとけばApache Tomcat + Apache Harmonyは動くと思います。
set CATALINA_HOME=C:\Java\apache-tomcat-6.0.30-wharmonyウェブブラウザ等でHTTPSでつなぐことはできたでしょうか?
set JAVA_HOME=C:\harmony-6.0-jdk-991881
set JRE_HOME=C:\harmony-6.0-jdk-991881\jre
で、OpenSSLで繋いでみる
openssl s_client
機能を使ってApache Tomcat + Harmonyのサーバーに接続してみましょう。
% openssl s_client -host zzz.com -port 8443とJava実装やブラウザだと出てこないエラーが出てきてしまいました。ググってみるに
CONNECTED(00000003)
depth=1 /C=JP/O=HOGE
verify error:num=19:self signed certificate in certificate chain
verify return:0
14052:error:04077068:rsa routines:RSA_verify:bad signature:rsa_sign.c:209:
14052:error:1408D07B:SSL routines:SSL3_GET_KEY_EXCHANGE:bad signature:s3_clnt.c:1447:
-cipher
を設定しないことが
原因のようで-cipher 'ALL:!kEDH'
を指定してちょっと絞り込みをしないといけないそうです。
% openssl s_client -host zzz.com -port 8443 -cipher 'ALL:!kEDH'これでApache Tomcat + HarmonyにOpenSSL s_clientで繋ぐことができるようになりました。
CONNECTED(00000003)
中略
depth=1 /C=JP/O=HOGE
verify error:num=19:self signed certificate in certificate chain
verify return:0
read R BLOCK
DONE
Apache HarmonyのJSSEのコード
Apache HarmonyのJSSEはjre/lib/boot/x-net{.jar,-src.jar}
にある
org.apache.harmony.xnet.provider.jsse
パッケージがそれに当たります。
x-net.jar
自体はコード署名されてないようなので、
CipherSuiteを追加し放題で
x-net.jar
に入れ替えても動きそうな雰囲気です。
JSSEプロバイダの定義はJSSEProvider.java
にあります。
コメントのところに割と詳しい説明があって以下のようなものが書かれています。
- サポートしているCipherSuites:別表
- 使用する共通鍵暗号アルゴリズム:IDEA,RC2,RC4,DES,3DES
- 使用するMacアルゴリズム:MD5, SHA-1
- 使用する鍵交換アルゴリズム: RSA, DH, DHE
SSLContext = TLS(=TLSv1)HarmonyJSSEがサポートしているCipherSuiteの一覧は以下の通りです。
KeyManagementFactory = X509
TrustManagementFactory = X509
TLS_NULL_WITH_NULL_NULLそして、そのうちデフォルトの設定で提供するCipherSuiteは以下の通りです。
TLS_RSA_WITH_NULL_MD5
TLS_RSA_WITH_NULL_SHA
TLS_RSA_EXPORT_WITH_RC4_40_MD5
TLS_RSA_WITH_RC4_128_MD5
TLS_RSA_WITH_RC4_128_SHA
TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5
TLS_RSA_WITH_IDEA_CBC_SHA
TLS_RSA_EXPORT_WITH_DES40_CBC_SHA
TLS_RSA_WITH_DES_CBC_SHA
TLS_RSA_WITH_3DES_EDE_CBC_SHA
TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA
TLS_DH_DSS_WITH_DES_CBC_SHA
TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA
TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA
TLS_DH_RSA_WITH_DES_CBC_SHA
TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA
TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
TLS_DHE_DSS_WITH_DES_CBC_SHA
TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
TLS_DHE_RSA_WITH_DES_CBC_SHA
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
TLS_DH_anon_EXPORT_WITH_RC4_40_MD5
TLS_DH_anon_WITH_RC4_128_MD5
TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA
TLS_DH_anon_WITH_DES_CBC_SHA
TLS_DH_anon_WITH_3DES_EDE_CBC_SHA
TLS_RSA_WITH_RC4_128_MD5今晩はこんなところで、、、
TLS_RSA_WITH_RC4_128_SHA
TLS_RSA_WITH_3DES_EDE_CBC_SHA
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
TLS_RSA_WITH_DES_CBC_SHA
TLS_DHE_RSA_WITH_DES_CBC_SHA
TLS_DHE_DSS_WITH_DES_CBC_SHA
TLS_RSA_EXPORT_WITH_RC4_40_MD5
TLS_RSA_EXPORT_WITH_DES40_CBC_SHA
TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
ではでは