ようやくすべての問題を解決できたので、私自身の質問に答えます。これらは、特定の問題を解決するために管理するために使用した設定/ファイルです。
クライアントのキーストアは、PKCS#12形式のファイルです。
- クライアントの公開証明書(この場合は自己署名CAによって署名されています)
- クライアントの秘密鍵
それを生成するためにpkcs12
、たとえば、OpenSSLのコマンドを使用しました。
openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12 -name "Whatever"
ヒント:バージョン0.9.8hではなく最新のOpenSSLを入手するようにしてください。これは、PKCS#12ファイルを適切に生成できないバグに悩まされているようです。
このPKCS#12ファイルは、サーバーがクライアントに認証を明示的に要求したときに、Javaクライアントがクライアント証明書をサーバーに提示するために使用されます。クライアント証明書認証のプロトコルが実際にどのように機能するかの概要については、TLSに関するウィキペディアの記事を参照してください(クライアントの秘密鍵が必要な理由もここで説明しています)。
クライアントのトラストストアは、ルートまたは中間のCA証明書を含む単純なJKS形式のファイルです。これらのCA証明書は、通信を許可するエンドポイントを決定します。この場合、クライアントは、トラストストアのCAの1つによって署名された証明書を提示するサーバーに接続できます。
これを生成するには、たとえば、標準のJavaキーツールを使用できます。
keytool -genkey -dname "cn=CLIENT" -alias truststorekey -keyalg RSA -keystore ./client-truststore.jks -keypass whatever -storepass whatever
keytool -import -keystore ./client-truststore.jks -file myca.crt -alias myca
このトラストストアを使用して、クライアントは、で識別されるCAによって署名された証明書を提示するすべてのサーバーで完全なSSLハンドシェイクを実行しようとしますmyca.crt
。
上記のファイルは、厳密にはクライアント専用です。サーバーもセットアップする場合、サーバーには独自のキーストアファイルとトラストストアファイルが必要です。Javaクライアントとサーバー(Tomcatを使用)の両方で完全に機能する例を設定するための優れたウォークスルーは、このWebサイトにあります。
問題/備考/ヒント
- クライアント証明書認証は、サーバーによってのみ実施できます。
- (重要!)サーバーが(TLSハンドシェイクの一部として)クライアント証明書を要求すると、証明書要求の一部として信頼できるCAのリストも提供されます。認証のために提示したいクライアント証明書がこれらのCAのいずれかによって署名されていない場合、それはまったく提示されません(私の意見では、これは奇妙な動作ですが、理由があると確信しています)。これが私の問題の主な原因でした。相手が私の自己署名クライアント証明書を受け入れるようにサーバーを適切に構成しておらず、リクエストでクライアント証明書を適切に提供しなかったことが問題であると想定したためです。
- Wiresharkを入手してください。優れたSSL/HTTPSパケット分析を備えており、問題のデバッグと発見に非常に役立ちます。
-Djavax.net.debug=ssl
これは、Java SSLデバッグ出力に慣れていない場合と似ていますが、より構造化されており、(おそらく)解釈が容易です。
Apachehttpclientライブラリを使用することは完全に可能です。httpclientを使用する場合は、宛先URLを同等のHTTPSに置き換え、次のJVM引数を追加します(HTTP / HTTPSを介したデータの送受信に使用するライブラリに関係なく、他のクライアントでも同じです)。 :
-Djavax.net.debug=ssl
-Djavax.net.ssl.keyStoreType=pkcs12
-Djavax.net.ssl.keyStore=client.p12
-Djavax.net.ssl.keyStorePassword=whatever
-Djavax.net.ssl.trustStoreType=jks
-Djavax.net.ssl.trustStore=client-truststore.jks
-Djavax.net.ssl.trustStorePassword=whatever