web-dev-qa-db-ja.com

ハンドシェイクが失敗するのはなぜですか(Java SSL)

HTTPS経由でWebサービスに接続しています。機能させるために必要だと思うことはすべて実行しましたが、最終的にはハンドシェイクに失敗します。

「スパム保護」のため、新しいユーザーとして2つを超えるリンクを投稿できないことがわかりました-たくさんのstackoverflowに感謝します...とにかく、ここにすべてのリンクがスペルアウトされたPastebin投稿へのリンクがあります...ここに「link#1」と記述します。これはこれらのリンクへの参照です: http://Pastebin.com/y4zGNRC7

  • HttpClient(サービスURLでGET)を使用して同じ動作を確認し、実際にCXFプロキシ経由でWebサービスを呼び出しました
  • 私はキーストアとトラストストアの両方を設定しています-「コード内」の方法(link#1)とシステムプロパティの設定の両方を試しました-つまりSystem.setProperty( "javax.net.ssl.keyStore"、 "mykeystore.jks" );
  • SSLデバッグはオンです(javax.net.debug = all)
  • SSLデバッグは、キーストアとトラストストアの両方の内容をぼかします(つまり、Java「それらについて知っている」のように見えます)-link#2
  • クライアントとサーバー間の通信が行われているようですが、何らかの理由でクラッシュしますlink#3
  • ブラウザとChromeの両方でクライアントとCA証明書を使用し、openssl s_clientを使用してサーバーに正常に接続しました
  • wiresharkは、Java(link#4)からのクライアントサーバートークを少なくし、次にChrome(link#5)から

もう1つの奇妙なことは、キーストアを設定した場合と設定しない場合で同じ動作をしているように見えることです(唯一の違いは、キーストアの内容を印刷すると、コンソール、それだけです)

問題をグーグルで調べてみたところ、stackoverflowに同様の投稿が多数ありましたが、何の助けにもなりませんでした。プロトコルバージョンを変更してみました( "TLSv1"、 "SSLv3"、奇妙なv2 Helloも)。何か助けていただければ幸いです-私が見落としたかもしれない基本的なことがあるかもしれません...私はここで絶望的になっています...ありがとう

PS私は実行中Java 1.6 update 30 on Fedora Core 15(64bit)

11
Jakub Hlavatý

問題は、キーストアとトラストストアが設定されていても、Javaがクライアント証明書をサーバーに送信しないことにしたことです。これは、サーバーが署名した証明書を要求したことが原因でした。 RootCA機関ですが、クライアント証明書はSubCA機関(RootCAが発行)によって署名されています。

元々、キーストアにはクライアント証明書、トラストストアにはSubCA証明書のみが含まれていました。次に、キーストアにもSubCA証明書を追加しようとしましたが、Javaはそれを無視しました。

つまり、これはハンシェイク失敗の謎を解決しますが、私の問題は解決しません。

私はそのために別の質問を作成しました... sigh : ---(なぜしないJava SSLハンドシェイク中にクライアント証明書を送信しますか?

5
Jakub Hlavatý

CAを含まないトラストストアが最も可能性の高い問題だと思います。 Java keytoolを使用して、サイトの証明書をcacertsファイルにインポートし、次のようなことを行うことができます。

keytool -keystore pathtocacerts -import -trustcacerts -v -alias aliasName -file root.crt

デフォルトのcacertsキーストアのパスワードはchangeitです。 cacertsファイルは通常jre/lib/securityディレクトリ。

3
Michael

あなたは十分な情報を提供していませんが、私はあなたのclientトラストストアが適切に設定されていないと思います。トラストストアには、他の証明書の署名に使用される信頼できる証明書が含まれており、サーバーおよびクライアントの証明書チェーンのルート証明書を含める必要があります。クライアントの鍵ストアには、クライアントのSSL証明書と秘密鍵が含まれています。