Java(tm) Secure Socket Extension JavaTM 2 SDK, Standard Edition, v 1.4 用 サンプルコード README ---------------------------------------------------------------------- 目次 ---------------------------------------------------------------------- - はじめに - サンプルキーストア - コード例 - トラブルシューティング ---------------------------------------------------------------------- はじめに ---------------------------------------------------------------------- この JSSE サンプルコード集では、JSSE を使用して Java(tm) ネットワーク 環境での通信を保護する方法を示す初歩的な実例を紹介します。 サンプルを理解するためには、Java および JSSE API に、ある程度慣れている 必要があります。詳細については、次のドキュメントを参照してください。 J2SDK: http://java.sun.com/doc/ JSSE: JSSE API のドキュメントは、Sun の J2SDK 実装またはドキュメント 集に含まれています。あるいは、次のサイトで参照できます。 http://java.sun.com/j2se/1.4/ja/docs/ja/guide/security/jsse/JSSERefGuide.html Sun 以外のベンダーの JSSE 実装を使用する場合は、その JSSE 実装 のドキュメントも調べてください。そして、セキュリティプロバイダ を構成する方法、classpath を設定する方法 (必要な場合)、https プロトコルを有効にする方法、HTTPS プロキシサーバを定義する方法 などについては、ベンダーから提供される指示に従ってください。 ---------------------------------------------------------------------- サンプルキーストア ---------------------------------------------------------------------- このサンプル集には、サンプルコードと一緒に使用できるサンプルのキーストア ファイルが 2 つ含まれています。どちらのファイルも、JKS キーストア形式で 格納されています。この形式は、Sun の J2SDK 実装によって使用される デフォルトの形式です。別のキーストア形式が必要な場合は、その新しいデ フォルト形式を認識できるように J2SDK を構成する必要があります。このド キュメントのこれ以降の部分では、J2SDK および JSSE の Sun の実装を使用 しているという前提のもとに説明を続けます。 JSSE は、証明書キーストアファイルを使用してクライアントとサーバを認証 します。 samplecacerts このファイルは、いくつかのベンダーの信頼できる証明書が 入っているという点で、ストック J2SDK cacerts ファイル とよく似ています。このファイルには、Duke (Java のマス コット) の信頼できる証明書も含まれています (後述の */testkeys を参照)。 このファイルは、次のいずれかとしてインストールできます。 /lib/security/jssecacerts または /lib/security/cacerts (アプリケーションを展開する前に、このファイルを、 本番用の cacerts ファイルに必ず置き換えてください。) このキーストアのパスワードは、J2SDK cacert の初期パス ワードと同じ changeit です。 */testkeys このファイルは、公開鍵や非公開鍵および証明書資料の ソースとしてコードサンプルによって使用されます。Duke 用の キーストア証明書エントリが入っています (上記の samplecacerts と同じ)。 このファイルの複製が、各サンプルディレクトリに入ってい ます。サンプルコードは、testkeys ファイルが現在の作業 ディレクトリにあることを前提としているからです。 このキーストアのパスワードは passphrase です。 Sun J2SDK ユーティリティの keytool を使用すれば、証明書およびキーストア ファイルを生成できます。 J2SDK および JSSE の Sun の実装を使用している場合は、適切な trustStore を使用するようにシステムを構成します。trustStore を指定する方法の詳細 については、J2SDK および JSSE のドキュメントを参照してください。 重要な注: cacerts ファイルを確認してください。 cacerts ファイルの CA を、証明書に署名し他のエンティティへ証明書を発行 するためのエンティティとして信頼する以上、この cacerts ファイルを注意 して管理する必要があります。cacerts ファイルには、信頼できる CA の証明書 以外を含めてはいけません。cacerts ファイルに含む信頼できるルート CA 証明 書を確認し、信頼に関する決定を下す責任は自分自身にあります。信頼できない CA 証明書を cacerts ファイルから削除するには。keytool コマンドの delete オプションを使用します。cacerts ファイルは、JRE のインストールディレクトリ にあります。このファイルを編集するためのアクセス権がない場合は、システム 管理者に連絡してください。 注: Microsoft の Internet Explorer または Netscape の Navigator など のブラウザを使用してサンプルの ssl サーバ (たとえば、 socket/server/ClassFileServer) にアクセスすると、アプリケーションが 「duke」の証明書を認識できないというメッセージダイアログが表示されます。 これは、正常な動作です。ブラウザに提示される自己署名された証明書は、 最初は信頼されないからです。 ---------------------------------------------------------------------- コード例 ---------------------------------------------------------------------- サンプルコード集は、SSL 接続のスタイルに基づいて、いくつかのディレクト リに分かれています。 urls URLReader.java この例では、URL を使用して安全なサイト上のリソースにアクセスす る方法を示します。デフォルトでは www.verisign.com に接続す るようになっていますが、前述の ClassFileServer に接続するよう にも変更できます。URL 要求を若干修正する必要があり、使用する https ホスト用のホスト証明書を作成する必要もあります。そうしな いと、「HTTPS ホスト名が間違っている」というエラーが起きてしま います。注: この動作は、HttpsURLConnection クラスの HostNameVerifier を使ってオーバーライドできます。 さらに、ファイアウォールの背後にいる場合は、https.proxyHost と https.proxyPort を設定する必要もあります。 使用方法: java URLReader URLReaderWithOptions.java この例は、上記の URLReader とよく似ていますが、メインメソッド に対する引数によって、システムプロパティを設定することができま す。これは、Java Runtime Environment に対する -D オプションに 代わるものとなります。 使用方法: java URLReaderWithOptions [-h proxyhost] [-p proxyport] ¥ [-k protocolhandlerpkgs] [-c ciphersarray] proxyHost = セキュアプロキシサーバのホスト名 (https.proxyHost) proxyPort = セキュアプロキシサーバのポート (https.proxyPort) protocolhandlerpkgs = プロトコルハンドラを "|" で区切っ て並べたリスト (java.protocol.handler.pkgs) ciphersarray = 有効な暗号スイートをカンマで区切って並べ たリスト (https.cipherSuites) sockets server ClassServer.java ClassFileServer.java このサンプルでは、ミニ Web サーバの実装を示します。単純 な HTTP または HTTPS 要求を処理できます (サポートしている のは GET メソッドのみ)。 デフォルトでは、サーバは SSL/TLS を使用しません。しかし、 コマンド行オプションによって SSL/TLS を有効にできます。 要求は、次のような形式でなければなりません。 GET / 使用方法: java ClassFileServer port docroot [TLS [true]] port = サーバが存在するポート docroot = ローカルディレクトリ階層のルート TLS = SSL/TLS サービスを有効にするフラグ (省略可能) true = クライアントが自身を認証することを要求する フラグ (省略可能)。このオプションを指定するには、 SSL/TLS サービスを有効にする必要がある。 注: Web ブラウザ経由で TLS ソケットに接続している場合は、 https プロトコルを使用することを指定してください。 例: https://localhost:2001/dir1/file1 そうしないと、SSL ハンドシェークを認識できないというエラー が起きることがあります。 client SSLSocketClient.java この例では、SSLSocket をクライアントとして使用して HTTP 要求 を送信し、HTTPS サーバから応答を受け取る方法を示します。 デフォルトでは www.verisign.com に接続するようになっていま すが、前述の ClassFileServer に接続するようにも簡単に変更で きます。注: GET 要求を若干変更しなければなりません。詳細は 前述の説明を参照してください。 このアプリケーションでは、クライアントがファイアウォールの 背後にないことを前提としています。 使用方法: java SSLSocketClient SSLSocketClientWithClientAuth.java この例は、上記の SSLSocketClient と似ていますが、サーバか ら要求されている場合にクライアント認証を実行するようにキー マネージャをセットアップする方法を示しています。 このアプリケーションでも、クライアントがファイアウォールの 背後にないことを前提としています。 使用方法: java SSLSocketClientWithClientAuth host port requestedfilepath SSLSocketClientWithTunneling.java この例では、プロキシトンネリングを実行して、ファイアウォール の背後からセキュア Web サーバにアクセスする方法を示します。 システムプロパティの https.proxyHost と https.proxyPort を 使用してプロキシホストへのソケット接続を作成してから、その ソケットの上位層として SSLSocket を使用します。 使用方法: java SSLSocketClientWithTunneling rmi Hello.java HelloImpl.java RMISSLClientSocketFactory.java RMISSLServerSocketFactory.java HelloClient.java この例は、JSSE を使用して、SSL トランスポート層の上で RMI を使 用する方法を示すものです。サーバは HelloImpl を実行し、クライ アントは HelloClient を実行します。 コンパイルに少し工夫が必要で、次のようなステップを実行します。 % javac *.java % rmic HelloImpl % rmiregistry % java ¥ -Djava.rmi.server.codebase="file:/current_working_dir/" ¥ HelloImpl (別のウィンドウで実行する) % java HelloClient (別のウィンドウで実行する) java.rmi.server.codebase パラメータの末尾のスラッシュに注目し てください。codebase を適切に指定しないと、 java.lang.ClassNotFoundException 例外を受け取ることになります。 さらに、RMI セキュリティマネージャがインストールされていること もあるので、注意が必要です。その場合は、次のようにして、適切な ネットワーク特権を与えておく必要があります。 permission java.net.SocketPermission "localhost:1099", "connect"; ---------------------------------------------------------------------- トラブルシューティング ---------------------------------------------------------------------- JSSE を使用する際に最もよく経験する問題の 1 つは、信頼性の判断を行なう 機構にとって未知の証明書を JSSE が受け取った場合の問題です。未知の 証明書を受け取ると、信頼性判断の機構は、その証明書を信頼できないという 例外をスローします。正しい信頼性キーストアが使用されていることと、JSSE が 正しくインストールされ、構成されていることを確認してください。 Sun のリファレンス実装では、返される例外エラーは次のようなものです。 javax.net.ssl.SSLException: Couldn't find trusted certificate このような信頼性に関する問題を調査するには、SSL デバッグ機構を使用でき ます。この件に関する詳細は、実装のドキュメントを参照してください。