javax.net.ssl.SSLHandshakeException:Web服务通信期间握手期间远程主机关闭连接


77

我正在获取javax.net.ssl.SSLHandshakeException:当我尝试通过Internet对Web服务进行HTTPS发布时,握手异常期间远程主机关闭了连接。但是相同的代码可用于其他Internet托管的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

实际上,这里有两种情况。当我作为独立的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

1
您能否发布完整的堆栈跟踪信息?
帽子的家伙

1
许多可能的原因中的另一个可能是连接断开或质量很低
comodoro

如果您使用其他程序来测试您的Web服务(例如curl或soap-ui),会发生什么?我有类似的问题,它可以使用curl,但不能从我的Java运行时(servicemix)使用。我怀疑它也可能是不包含服务器证书的客户端“证书”。
рüффп

如果有人通过gradle到达了此页面,而这不是OP所要求的,请确保将JAVA_HOME设置为Java 8或更高版本。
Sridhar Sarnobat,

Answers:


70

Java 7默认为TLS 1.0,如果不接受该协议,则可能导致此错误。我在Tomcat应用程序和不再接受TLS 1.0连接的服务器时遇到了这个问题。我加了

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

Java选项,并对其进行了修复。(Tomcat正在运行Java7。)


2
我应该在哪里添加那行代码?在哪个文件里面?你能告诉目录路径吗?
hamed 16-10-21

2
它不是代码,而是调用Java可执行文件时设置的Java选项的一部分。确切答案取决于您的操作系统和程序。对于本例中Windows上的Tomcat,运行Tomcat7w将使您入门,然后修改Java选项。在其他情况下,可以将选项添加到初始化文件中,或者对于java.exe命令行,将其添加到初始化文件中。我绝对建议您研究Java选项,而不是在您不熟悉它们的情况下盲目添加。docs.oracle.com/javase/7/docs/technotes/tools/windows/java.html是一个好的开始。
埃里卡·凯恩

1
@EricaKane-很高兴得到答案。但是,我们如何调试此问题并找出原因呢?(即我们如何找到您的解决方案?)
MasterJoe

如果您要处理的是面向公众的网站,则可以使用SSL Labs或其他工具查看它们将接受哪种协议。如果他们不再接受TLS 1.0(坦率地说,大多数人不接受)并且您正在使用Java 7,则需要实现此功能。至于我最初是如何专门调试的,我不再记得了。
埃里卡·凯恩

2
这对于Java 8和Java Web Start似乎仍然如此。刚刚添加<property name="https.protocols" value="TLSv1.1,TLSv1.2"/>到JNLP文件中以使Web Start再次可操作...
Dirk Hillbrecht

29

我遇到了同样的问题,并通过添加以下内容解决了该问题:

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

openConnection方法之前。


19

还没有答案,但是评论太多了。显然这不是服务器证书问题;其症状是完全不同的。从系统的POV来看,服务器在握手期间似乎正在关闭。有两种可能性:

服务器确实正在关闭,这是一个SSL / TLS协议违规,尽管这是一个相当小的攻击。有很多原因可能导致服务器无法与您握手,但服务器应首先发送致命警报,您的JSSE或weblogic等效对象应指出该警报。在这种情况下,如果您能够(并被允许)与经验丰富的服务器管理员通信,则服务器日志中可能会包含一些有用的信息。或者,您可以尝试在客户端计算机上放置一台网络监视器,或者将其关闭到足够近的距离,以查看您的所有流量;我个人喜欢www.wireshark.org。但这通常仅显示关闭是在ClientHello之后立即进行的,并不能将范围缩小很多。您没有说是否应该为此服务器配置“客户端证书”(实际上是Java的Key&cert,形式为privatekeyEntry)。可能会认为这是一种攻击并且故意关闭协议而违反了协议,即使他们正式发出了警报也是如此。

或者,网络中的某些中间盒(通常是防火墙或所谓的透明代理)正在决定它不喜欢您的连接并强迫关闭。您使用的代理显然是可疑的。当您说“相同的代码”适用于其他主机时,请确认您是通过同一个代理(不仅仅是代理)并使用HTTPS(不清除HTTP)来确定的。如果不是这样,请尝试通过代理通过HTTPS对其他主机进行测试(您不必发送完整的SOAP请求,只需发送GET /即可)。如果可以,请尝试在没有代理或可能没有其他代理的情况下进行连接,然后通过代理将HTTP(非S)通过代理连接到主机(如果两者均支持clear),然后查看它们是否起作用。

如果您不介意发布实际的主机(但绝对不是任何身份验证凭据),其他人可以尝试一下。或者,您可以访问www.ssllabs.com并要求他们测试服务器(不发布结果);这将尝试SSL / TLS连接的几种常见变体,并报告所看到的任何错误以及任何安全漏洞。



8

我认为您缺少证书。

您可以尝试使用InstallCerts应用生成它们。在这里您可以看到如何使用它:https : //github.com/escline/InstallCert

获得证书后,需要将其放在jdk主页中的安全目录下,例如:

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

让我知道是否有效。


两条链接都
断开

@kane我已经更新了链接...顺便说一句,我的回答不是试图解释如何生成证书,而是将证书放在何处。我添加了该链接作为上下文信息,以防OP希望深入了解证书生成。
费德里科广场

7

我在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密码学扩展(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


3

在我的情况下,我遇到了这个问题,因为由于配置文件中的错字,我给了服务器一个不存在的证书。服务器没有引发异常,而是像平常一样继续进行,并向客户端发送了空证书。因此,可能值得检查以确保服务器提供了正确的响应。

使用Jersey客户端连接到服务器时,我遇到此错误。我解决该问题的方法是调试该库,并在尝试读取时看到它确实收到了EOF。我还尝试使用网络浏览器进行连接,并获得了相同的结果。

只是在这里写,以防最终对任何人有帮助。


2

我遇到了类似的问题,发现我碰错了端口。修复端口后,效果很好。


1

感谢所有人分享您的答案和示例。相同的独立程序通过少量更改并添加下面的代码行为我工作。

在这种情况下,密钥库文件是由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

我在Java 1.6中遇到此问题。在Java 1.7下运行修复了我对该问题的特殊解释。我认为根本原因是我所连接的服务器必须要求比1.6版更高的加密强度。


1

我有同样的错误,但就我而言,这是由Intellij IDE中的DEBUG模式引起的。调试减慢了库的速度,然后服务器在握手阶段结束了通信。标准的“运行”运行完美。


1

我使用Java 8运行应用程序,并且Java 8将安全证书添加到其信任库中。然后,我切换到Java 7,并将以下内容添加到VM选项中:

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

我只是简单地指出了证书所在的位置。


1

您可以在您当前的Java程序中编写以下代码

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

要么

System.setProperty("http.proxyHost", "proxy.com");

System.setProperty("http.proxyPort", "911");


0

我使用的是与MacBook上的Keychain一起导出的p12,但是,它不适用于我的java-apns服务器代码。我所要做的就是创建一个新的P12密钥说在这里,用我已经生成的PEM键:

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

然后将路径更新到该新的p12文件,一切正常。


0

您将如何解决该问题,方法是:

  1. 设定值

  2. 搜索“网络”

  3. 选择“使用IDEA常规代理设置作为默认Subversion”



0

使用TLSv1.2警报的基础:致命,handshake_failure我在调试后使用此线程获得previos答案

-Djavax.net.debug =全部

我去了https://www.ssllabs.com/,发现Web服务器要求在2015年6月弃用SSLv3连接,并在JDKu31发行说明中弃用

ssllabs结果

我在该行中编辑了$ {java_home} /jre/lib/security/java.security

jdk.tls.disabledAlgorithms = SSLv3,RC4,DES,MD5 withRSA,DH keySize <1024,
EC keySize <224,3DES_EDE_CBC,anon,NULL

jdk.tls.disabledAlgorithms = RC4,DES,MD5 withRSA,DH keySize <1024,
EC keySize <224,3DES_EDE_CBC,anon,NULL

最后一步,我得到了这个错误

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target [javax.net.ssl.SSLHandshakeException]

在此答案PKIX路径构建失败之后,我解决了使用java keytool安装证书的问题,并“无法找到到请求目标的有效证书路径”



-2

我曾经遇到过同样的问题。我认为是因为网址

字符串xmlServerURL =“ https://example.com/soap/WsRouter ”;

检查其是否正确?

javax.net.ssl.SSLHandshakeException 是因为服务器由于以下原因而无法连接到指定的网址-

  • 网站的身份未得到验证。
  • 服务器的证书与URL不匹配。
  • 或者,服务器的证书不受信任。

SSLHandshakeException不是这些原因引起的。
洛恩侯爵,

-4

这就是解决我的问题的方法。

如果您尝试使用调试器,请确保断点不在URL或URLConnection上,只需将断点放在BufferReader或while循环内即可。

如果没有任何效果,请尝试使用apache库http://hc.apache.org/index.html

无需SSL,无需JDK更新,甚至无需设置属性,只需简单的技巧即可:)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.