web-dev-qa-db-ja.com

javax.net.ssl.SSLHandshakeException:Webサービス通信中のハンドシェイク中にリモートホストが接続を閉じました

インターネット経由でWebサービスのHTTPS Postを実行しようとすると、javax.net.ssl.SSLHandshakeException:リモートホストがハンドシェイク中に接続をクローズしました例外が発生します。しかし、同じコードが他のインターネットでホストされているWebサービスにも機能します。私はたくさんのことを試しました、何も助けていません。ここに私のサンプルコードを掲載しました。誰かが私を助けてこの問題を解決してもらえますか?

public static void main(String[] args) throws Exception {

    String xmlServerURL = "https://example.com/soap/WsRouter";
    URL urlXMLServer = new URL(xmlServerURL);
    // URLConnection supports HTTPS protocol only with JDK 1.4+ 
    Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(
            "xxxx.example.com", 8083));
    HttpURLConnection httpsURLConnection = (HttpURLConnection) urlXMLServer
            .openConnection(proxy);
    httpsURLConnection.setRequestProperty("Content-Type","text/xml; charset=utf-8");
    //httpsURLConnection.setDoInput(true);
    httpsURLConnection.setDoOutput(true);
    httpsURLConnection.setConnectTimeout(300000);
    //httpsURLConnection.setIgnoreProxy(false);
    httpsURLConnection.setRequestMethod("POST"); 
    //httpsURLConnection.setHostnameVerifier(DO_NOT_VERIFY); 
    // send request
    PrintWriter out = new PrintWriter(
            httpsURLConnection.getOutputStream());
    StringBuffer requestXML = new StringBuffer();
    requestXML.append(getProcessWorkOrderSOAPXML());   
    // get list of user     
    out.println(requestXML.toString()); 
    out.close();
    out.flush();
    System.out.println("XML Request POSTed to " + xmlServerURL + "\n");
    System.out.println(requestXML.toString() + "\n"); 
    //Thread.sleep(60000);  
    // read response

    BufferedReader in = new BufferedReader(new InputStreamReader( 
            httpsURLConnection.getInputStream()));
    String line;
    String respXML = "";
    while ((line = in.readLine()) != null) {
        respXML += line;
    }
    in.close();

    // output response
    respXML = URLDecoder.decode(respXML, "UTF-8"); 
    System.out.println("\nXML Response\n");
    System.out.println(respXML);
}

フルスタックトレース:

Exception in thread "main" javax.net.ssl.SSLHandshakeException: Remote Host closed connection during handshake
       at Sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.Java:946)
       at Sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.Java:1312)
       at Sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.Java:1339)
       at Sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.Java:1323)
       at Sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.Java:563)
       at Sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.Java:185)
       at Sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.Java:1091)
       at Sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.Java:250)
       at com.labcorp.efone.vendor.TestATTConnectivity.main(TestATTConnectivity.Java:43)
Caused by: Java.io.EOFException: SSL peer shut down incorrectly
       at Sun.security.ssl.InputRecord.read(InputRecord.Java:482)
       at Sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.Java:927)
       ... 8 more

実際には、ここに2つのシナリオがあります。スタンドアロンのJavaプログラムとして作業していると、上記の例外が発生します。しかし、weblogicアプリケーションサーバーで実行しようとすると、次のような例外が発生します。何が原因なのでしょうか。

Java.io.IOException: Connection closed, EOF detected
    at weblogic.socket.JSSEFilterImpl.handleUnwrapResults(JSSEFilterImpl.Java:637)
    at weblogic.socket.JSSEFilterImpl.unwrapAndHandleResults(JSSEFilterImpl.Java:515)
    at weblogic.socket.JSSEFilterImpl.doHandshake(JSSEFilterImpl.Java:96)
    at weblogic.socket.JSSEFilterImpl.doHandshake(JSSEFilterImpl.Java:75)
    at weblogic.socket.JSSEFilterImpl.write(JSSEFilterImpl.Java:448)
    at weblogic.socket.JSSESocket$JSSEOutputStream.write(JSSESocket.Java:93)
    at Java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.Java:82)
    at Java.io.BufferedOutputStream.flush(BufferedOutputStream.Java:140)
    at Java.io.FilterOutputStream.flush(FilterOutputStream.Java:140)
    at weblogic.net.http.HttpURLConnection.writeRequests(HttpURLConnection.Java:192)
    at weblogic.net.http.HttpURLConnection.getInputStream(HttpURLConnection.Java:433)
    at weblogic.net.http.SOAPHttpsURLConnection.getInputStream(SOAPHttpsURLConnection.Java:37)
    at com.labcorp.efone.service.impl.WorkOrderServiceImpl.processATTWorkOrder(ATTWorkOrderServiceImpl.Java:86)
    at com.labcorp.efone.bds.WorkOrderBusinessDelegateImpl.processATTWorkOrder(WorkOrderBusinessDelegateImpl.Java:59)
    at com.labcorp.efone.actions.ATTWorkOrderAction.efonePerformForward(ATTWorkOrderAction.Java:41)
    at com.labcorp.efone.actions.EfoneAction.efonePerformActionForward(EfoneAction.Java:149)
    at com.labcorp.efone.actions.EfoneAction.execute(EfoneAction.Java:225)
    at org.Apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.Java:484)
    at org.Apache.struts.action.RequestProcessor.process(RequestProcessor.Java:274)
    at org.Apache.struts.action.ActionServlet.process(ActionServlet.Java:1482)
    at org.Apache.struts.action.ActionServlet.doPost(ActionServlet.Java:525)
    at javax.servlet.http.HttpServlet.service(HttpServlet.Java:751)
    at javax.servlet.http.HttpServlet.service(HttpServlet.Java:844)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.Java:280)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.Java:254)
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.Java:136)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.Java:341)
    at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.Java:25)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.Java:79)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:330)
    at com.labcorp.efone.security.EfoneAuthenticationFilter.doFilter(EfoneAuthenticationFilter.Java:115)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.Java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.Java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.Java:160)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.Java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.Java:259)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.Java:79)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.Java:3367)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.Java:3333)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.Java:321)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.Java:120)
    at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.Java:57)
    at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.Java:2220)
    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.Java:2146)
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.Java:2124)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.Java:1564)
    at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.Java:254)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.Java:295)
    at weblogic.work.ExecuteThread.run(ExecuteThread.Java:254)
Exception: Java.io.IOException: Connection closed, EOF detected
61
user3216923

Java 7はデフォルトでTLS 1.0に設定されているため、そのプロトコルが受け入れられないとこのエラーが発生する可能性があります。 Tomcatアプリケーションと、TLS 1.0接続を許可しなくなるサーバーでこの問題に遭遇しました。追加した

-Dhttps.protocols=TLSv1.1,TLSv1.2

javaオプションとそれを修正しました。 (TomcatはJava 7を実行していました。)

59
Erica Kane

私は同じ問題に直面しました、私はそれを加えてそれを解決しました:

System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2");

before openConnectionメソッドの前。

21
Kamal SABBAR

まだ答えではありませんが、コメントするには多すぎます。これは明らかにサーバー証明書の問題ではありません。その症状はまったく異なります。システムのPOVから、サーバーはハンドシェイク中に閉じているように見えます。 2つの可能性があります。

サーバーは本当に終了しています。これはかなり小規模なものですが、SSL/TLSプロトコル違反です。サーバーとのハンドシェイクに失敗する可能性がある理由はいくつかありますが、最初に致命的なアラートを送信する必要があります。これは、JSSEまたは同等のWeblogicが示すとおりです。この場合、あなたが知識のあるサーバ管理者と通信することができる(そして許可されている)ならば、サーバログには役に立つ情報があるかもしれません。または、クライアントコンピュータにネットワークモニタを配置するか、またはすべてのトラフィックが見えるほど近くに配置することもできます。個人的にはwww.wireshark.orgが好きです。しかし、これは通常、ClientHelloの直後にクローズが発生したことだけを示しています。このサーバー用の「クライアント証明書」(実際にはkey&cert、Java privateKeyEntryの形式)を想定していて、これを構成しているかどうかはわかりません。それがサーバによって要求され、正しくない場合、may攻撃的であると認識し、公式には警告を送信しなければならないにもかかわらずプロトコルを閉じて違反します。

あるいは、ネットワーク内のミドルボックス、ほとんどの場合はファイアウォールまたは透過透過プロキシと呼ばれるものが、接続を好まないと判断して強制終了します。あなたが使うプロキシは明らかに疑わしいものです。 「同じコード」が他のホストにも適用されると言う場合は、同じプロキシ(単なるプロキシではない)を使用し、HTTPS(明確なHTTPを使用しない)を使用するかどうかを確認します。そうでない場合は、プロキシを介してHTTPSで他のホストにテストしてみてください(十分な場合は完全なSOAP要求を送信する必要はありません)。可能であれば、プロキシなしで、あるいはおそらく別のプロキシなしで接続し、プロキシ経由でHTTP(Sではなく)をホストに接続し(両方ともサポートされている場合)、それらが機能するかどうかを確認します。

実際のホストを公開しても構わない場合(ただし、認証資格情報は絶対に指定しないでください)、他の人が試すことができます。あるいは、www.ssllabs.comにアクセスしてサーバーにテストを依頼することもできます(結果を公開せずに)。これはSSL/TLS接続にいくつかの一般的なバリエーションを試してみて、それが見るエラーやセキュリティの弱点を報告します。

15

問題を診断するための最初のステップは、VMオプションを指定してJavaを起動することによって、クライアントを起動することです(サーバーを自分で実行している場合は、サーバーのプライベートテストインスタンス)。

-Djavax.net.debug=all

https://blogs.Oracle.com/Java-platform-group/entry/diagnosing_tls_ssl_and_https も参照してください。

8
Henno Vermeulen

GlassfishアプリケーションサーバーとOracle JDK/JREで同様の問題が発生しましたが、Open JDK/JREでは発生しません。

SSLドメインに接続するとき、私はいつも遭遇しました:

javax.net.ssl.SSLHandshakeException: Remote Host closed connection during handshake
...
Caused by: Java.io.EOFException: SSL peer shut down incorrectly

私にとっての解決策は、Java Cryptography Extension(JCE)無制限強度管轄ポリシーファイルをインストールすることでした。これは、サーバーがOracle JDKに含まれていない証明書しか認識できないためです。デフォルトでは、OpenJDKだけがそれらを含みます。インストールした後、すべてが魅力のように働いた。


JCE 7: http://www.Oracle.com/technetwork/Java/javase/downloads/jce-7-download-432124.html

JCE 8: http://www.Oracle.com/technetwork/Java/javase/downloads/jce8-download-2133166.html

7
McIntosh

証明書が紛失していると思います。

あなたはInstallCertsアプリを使ってそれらを生成してみることができます。ここであなたはそれを使用する方法を見ることができます: https://github.com/escline/InstallCert

証明書を取得したら、それをjdkホーム内のセキュリティディレクトリに置く必要があります。次に例を示します。

C:\Program Files\Java\jdk1.6.0_45\jre\lib\security

それがうまくいくかどうか私に知らせてください。

7
Federico Piazza

私は同様の問題に遭遇し、私は間違ったポートを打っていたことがわかりました。ポートを修正した後、物事はうまくいった。

2
user3225313

私の場合は、configファイルの入力ミスが原因で、サーバーに存在しない証明書を与えたため、この問題が発生しました。例外をスローする代わりに、サーバーは通常どおりに処理を進め、空の証明書をクライアントに送信しました。したがって、サーバーが正しい応答を提供していることを確認することを確認する価値があります。

Jersey Clientを使用してサーバーに接続しているときにこのエラーが発生しました。私がそれを解決した方法は、ライブラリをデバッグして、それが読み込もうとした瞬間に実際にEOFを受け取ったことを見ることでした。 Webブラウザを使って接続しても同じ結果が得られました。

誰かを助けることになった場合に備えて、これをここに書くだけです。

1
Parisbre56

私は自分のアプリケーションをJava 8で実行し、Java 8がセキュリティ証明書をトラストストアに持ってきました。それから私はJava 7に切り替えて、VM optionsに以下を追加しました:

-Djavax.net.ssl.trustStore=C:\<....>\Java8\jre\lib\security\cacerts

単に私は証明書がある場所を指さしました。

1
Rare Case

あなたの答えと例を共有してくれてありがとう。同じスタンドアロンプ​​ログラムが、小さな変更と以下のコード行の追加によって私のために働きました。

この場合、キーストアファイルはWebサービスプロバイダによって提供されました。

// Small changes during connection initiation.. 

// Please add this static block 

      static {

        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()

            {   @Override

        public boolean verify(String hostname, SSLSession arg1) {

        // TODO Auto-generated method stub

                if (hostname.equals("X.X.X.X")) {

                    System.out.println("Return TRUE"+hostname);

                    return true;

                }

                System.out.println("Return FALSE");

                return false;

              }
               });
         }


String xmlServerURL = "https://X.X.X.X:8080/services/EndpointPort";


URL urlXMLServer = new URL(null,xmlServerURL,new Sun.net.www.protocol.https.Handler());


HttpsURLConnection httpsURLConnection = (HttpsURLConnection) urlXMLServer               .openConnection();

// Below extra lines are added to the same program

//Keystore file 

 System.setProperty("javax.net.ssl.keyStore", "Drive:/FullPath/keystorefile.store");

 System.setProperty("javax.net.ssl.keyStorePassword", "Password"); // Password given by vendor

//TrustStore file

System.setProperty("javax.net.ssl.trustStore"Drive:/FullPath/keystorefile.store");

System.setProperty("javax.net.ssl.trustStorePassword", "Password");
1
Laxman

私はJava 1.6でこの問題に遭遇しました。 Java 1.7の下で走らせることは私の問題の特定の表現を修正しました。根本的な原因は、接続していたサーバーが1.6で利用可能だったものよりも強力な暗号化を必要としていたことにあると思います。

1
matt forsythe

あなたの現在のJavaプログラムの内部にこのコードを書くことができます

System.setProperty( "https.protocols"、 "TLSv1.1");

または

System.setProperty( "http.proxyHost"、 "proxy.com"); System.setProperty( "http.proxyPort"、 "911");

1
Srinivas Thouti

私は私のMacBookでKeychainと一緒にエクスポートしたp12を使っていたが、それは私のJava-apnsサーバーコードではうまくいかなかった。私がしなければならなかったのは、私がすでに生成したpemキーを使って、 here のように新しいp12キーを作成することでした:

openssl pkcs12 -export -in your_app.pem -inkey your_key.pem -out your_app_key.p12

それからその新しいp12ファイルへのパスを更新し、すべてが完璧に機能しました。

0
Cyberdelphos

同じエラーが発生しましたが、私の場合はIntellij IDEのデバッグモードが原因でした。デバッグはライブラリの速度を落とし、その後サーバーはハンドシェイクフェーズで通信を終了しました。標準の "RUN"は完璧に機能しました。

0
Bechyňák Petr

私は一度同じ問題に直面しました。 URLだからだと思う

文字列xmlServerURL = " https://example.com/soap/WsRouter ";

その適切なものかどうかを確認してください?

javax.net.ssl.SSLHandshakeExceptionは、次の理由により、サーバーが指定されたURLに接続できないためです -

  • Webサイトの身元が確認されていません。
  • サーバーの証明書がURLと一致しません。
  • または、サーバーの証明書が信頼されていません。
0
Manjunath Adoor

どのようにあなたはそれを解決することになるでしょう

  1. 設定

  2. 「ネットワーク」を検索

  3. 「デフォルトのSubversionとしてIDEA一般プロキシ設定を使用」を選択します。

0
W.Shawn