2

私は次の問題を抱えています。SSL経由で呼び出すことができるエンドポイントを持つWebサービスと、クライアント証明書を使用してクライアントを認証することによってのみ呼び出すことができるWebサービスがあります。問題は、クライアント側の証明書を動的に変更したいということです。私のコードは次のとおりです。

System.setProperty("javax.net.ssl.trustStore", "cacerts.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
//...
// first web service call, without client side certificate -> OK
//...
System.setProperty("javax.net.ssl.trustStore", "cacerts.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
System.setProperty("javax.net.ssl.keyStore", "keystore1.jks");
System.setProperty("javax.net.ssl.keyStoreType", "JKS");
System.setProperty("javax.net.ssl.keyStorePassword", "password");
//...
// second web service call

私の問題は2回目の電話です。ここで例外が発生します:

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

コードの2番目の部分だけを実行すると、すべてが正常に機能します(したがって、クライアント証明書を含むkeystore.jksがあり、サーバーは要求を正しく認証します)。私は何が間違っているのですか?Webサービスを呼び出すときにクライアント側の証明書を動的に変更するにはどうすればよいですか?

4

1 に答える 1

3

私が起こっているのはSSLContext、SSLソケットファクトリにデフォルトのJSSEを使用している方法を使用していることです。ドキュメントから、SSLコンテキストは、最初に作成されたときに1回だけ構成され、最初の使用後にシステムプロパティを設定しても効果がないように見えます。

ApacheHttpClientの使用をお勧めします。それらのSSLSocketFactory実装により、キーストアとトラストストアをプログラムでカスタマイズして、そのファクトリとの接続に使用できます。その上、HttpClientは、JDKですぐに使用できるものよりもはるかに多くの機能と構成オプションを提供します。

于 2012-04-16T14:24:02.987 に答える