| List | Java SSL | English |

Java SSL - sslecho
SSLソケット通信(クライアント証明書)

ダウンロード: sslecho.zip

はじめに

Java 2 Standard Edition 1.4.xよりSSLソケット(JSSE)が標準添付となりました。 SSL対応Webサーバに簡単に接続できるようになったほか(URLクラスに"https:"を指定するか、HTTPSConnectionクラスを使用)、開発者は独自のネットワークサービスをSSLで保護することが簡単にできるようになりました。

このサンプルの特徴はクライアント側も公開鍵証明書を提示する点です。 SSL通信では、サーバ側は必ず証明書を提示するため、クライアントはサーバの身分確認が行えます。 しかし通常、クライアントの証明書の提示は必須ではないため、サーバはクライアントの身分確認を行わないケースがほとんどです。 このサンプルでは、クライアントも証明書を提示するため、双方で本人確認が可能で、高いセキュリティが求められる場面で有効です。

このサンプルは、O'Reilly刊『Java Network Programming』(Elliotte Rusty Harold著)のサンプルコードを元に作成しました。

ファイル構成

server/server.classサーバ実行ファイル ← 削除(コンパイルしてください)
server/server.javaそのソース
server/server.jksサーバの隠蔽鍵を納めた鍵保管庫(例)
server/server.cerその公開鍵証明書(例)
server/clients.jksサーバが信頼する証明書の保管庫(例)
  
client/client.classクライアント実行ファイル ← 削除(コンパイルしてください)
client/client.javaそのソース
client/client.jksクライアントの隠蔽鍵を納めた鍵保管庫(例)
client/client.cerその公開鍵証明書(例)
client/servers.jksクライアントが信頼する公開鍵証明書の保管庫(例)
  
sslecho.htmlこの説明書

実行方法

あるマシンでサーバを、別のマシンでクライアントを実行します。
両者を同じマシンで実行してもかまいません。
サーバはサンプルのserverディレクトリ、クライアントはclientディレクトリに移ってから実行してください。

	[Server]
	C:\SSLECHO> cd server
	C:\SSLECHO\SERVER> java server
	
	[Client]
	C:\SSLECHO> cd client
	C:\SSLECHO\CLIENT> java client -host <server-name>

<server-name>はサーバが動作するマシンの名前かIPアドレスです。
同じマシンの場合は<server-name>を"localhost"にしてください。
サーバは同時に何人のクライアントでも接続可能です。

接続が完了するとクライアント側でタイプした文字が行単位でサーバに送られ、サーバは同じ文字をクライアントに返してきます。これがクライアント側の画面に表示されます。 終了するにはクライアント側からピリオド(.)だけの行をタイプしてください。

	server = www.ssjava.net:7000
	factory created
	socket created
	sender started
	receiver started
	handshake completed
	getCipherSuite: SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
	getProtocol: TLSv1
	getPeerHost: www.ssjava.net
	Cert #0: CN=Sample echo server, OU=Tech, O=Kobu.Com, ...
	Hello server
	Hello server
	Bye bye server
	Bye bye server
	.
	sender exit
	.
	receiver exit

デフォルトではサーバ側しか証明書を提示しませんが、-clientauthオプションを指定すると、クライアント側も証明書を提示しないと接続が完了しません。

	[Server]
	C:\SSLECHO\SERVER> java server -clientauth
	
	[Client]
	C:\SSLECHO\CLIENT> java client -host <server-name> -clientauth

リコンパイル

サーバ、クライアントそれぞれのソースのリコンパイル方法は次のとおりです。

	[Server]
	C:\SSLECHO\> cd server
	C:\SSLECHO\SERVER> javac server.java
	
	[Client]
	C:\SSLECHO\> cd client
	C:\SSLECHO\CLIENT> javac client.java

鍵保管庫および証明書保管庫の作成

このサンプルには、ファイル一覧にあるとおり、SSLアプリケーションの動作にあらかじめ必要なファイルが用意されています。

これらファイルの作成方法は次のとおりです。 詳細はJavaの付属ツールのドキュメントのkeytoolの説明書をごらんください。

サーバ側の証明書の準備(必須)

まずサーバの鍵保管庫(keystore)に隠蔽鍵(private key)を作成します。
次の例はserver.jksという名前の保管庫にserverという名前(alias)の隠蔽鍵を作成します。 サンプルコードでは保管庫および隠蔽鍵のパスワードはすべてchangeitになってます。

	keytool -genkey -keystore server.jks -alias server

次に作成した隠蔽鍵に対応する公開鍵(public key)をserver.cerという証明書ファイルに取り出します。

	keytool -export -keystore server.jks -alias server -file server.cer

最後に、このサーバの証明書を、クライアントが使用する信頼できる公開鍵証明書の保管庫(truststore)に追加します。
ここでは、server.cerに保存した証明書をservers.jksという名前の証明書保管庫にserver1という名前で格納します。

	keytool -import -keystore servers.jks -alias server1 -file server.cer

サーバの鍵保管庫(単数のserver.jks)はserver.classと同一ディレクトリに置いてください。
クライアント用の証明書保管庫(複数のservers.jks)はclient.classと同一ディレクトリに置いてください。

注意:

「private key」は「非公開鍵」と訳されることが多いですが、「public key」の訳が「公開鍵」であるためまぎらわしいので、ここでは「隠蔽鍵」とします。

keytoolはデフォルトでDSA方式の鍵対を作成します。 SSL対応WebサーバではRSA鍵が使用されます。 SSL証明書用には-keyalg RSAを指定します。

keytoolはデフォルトでバイナリ形式の証明書ファイルを出力します。 RFC1421準拠のテキスト形式を出力する場合は-rfcを指定します。 取り込み(-import)には形式を指定する必要はありません。

クライアント側の証明書の準備(-clientauthを指定する場合)

サーバの場合と手順は同じです。
まずクライアントの鍵保管庫(client.jks)に隠蔽鍵(client)を作成します。

	keytool -genkey -keystore client.jks -alias client

次に公開鍵証明書をclient.cerに取り出します。

	keytool -export -keystore client.jks -alias client -file client.cer

この証明書をclient1という名前でサーバの証明書保管庫(clients.jks)に追加します。

	keytool -import -keystore clients.jks -alias client1 -file client.cer

クライアントの鍵保管庫(単数のclient.jks)はclient.classと同一ディレクトリに置いてください。
サーバ用の証明書保管庫(複数のclients.jks)はserver.classと同一ディレクトリに置いてください。

デフォルトの鍵・証明書保管庫の場所

このサンプルでは、既存のJavaの設定を変更しなくて済むよう、クラスファイルと同じディレクトリに鍵保管庫(keystore)と証明書保管庫(truststore)を置いて使用しています。

しかし、証明書保管庫については、通常はJSSEのデフォルト位置(<java.home>/jre/lib/security/jssecacerts)に置くことで、サンプルコードのように、わざわざ保管庫の位置を指定する必要はありません。

このサンプルに付属の証明書は上記の手順で弊社が作成した自己署名の証明書ですが、第三者機関(VerisignやTharteなどの証明局)に発行してもらった証明書の場合、証明局の証明書が証明書保管庫になければなりません。 そのかわり当の証明書を保管庫に入れる必要はなくなります。 Verisignなど有名な証明局の証明書はすでにJavaのデフォルトの保管庫(<java.home>/jre/lib/security/cacerts)に納められています。

以上詳細はJavaのセキュリティ関連ドキュメント、JSSEのリファレンスを参照してください。

参考

初版: 2003/04/28

制作: 荒井文吉
提供: 横浜工文社(www.kobu.com

公開するサンプルは試作品で、完全なものではありません。
サンプルの転載はご遠慮ください。

Copyright © 2003 Kobu.Com. All rights reserved.