我在 javax.net.ssl.SSLHandshakeException:握手期间远程主机关闭连接异常当我尝试通过互联网进行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
答案 0 :(得分:59)
Java 7默认为TLS 1.0,当不接受该协议时,可能会导致此错误。我遇到了Tomcat应用程序和不再接受TLS 1.0连接的服务器的问题。我添加了
-Dhttps.protocols=TLSv1.1,TLSv1.2
到Java选项并修复它。 (Tomcat运行的是Java 7。)
答案 1 :(得分:21)
我遇到了同样的问题,我通过添加:
解决了这个问题System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2");
在 openConnection 方法之前。
答案 2 :(得分:15)
尚未回答,但评论过多。这显然不是服务器证书问题;这种症状完全不同。从您的系统的POV,服务器似乎在握手期间关闭。有两种可能性:
服务器确实正在关闭,这是一个SSL / TLS协议违规,虽然相当小;服务器可能无法与您握手的原因有很多,但它应首先发送致命警报,您的JSSE或weblogic等效应该指示。在这种情况下,如果您能够(并且允许)与知识渊博的服务器管理员进行通信,则服务器日志中可能会有一些有用的信息。或者您可以尝试在您的客户端计算机上安装网络监视器,或者一个足够近的网络监视器查看您的所有流量我个人喜欢www.wireshark.org。但这通常只表明关闭是在ClientHello之后立即出现的,而后者并未缩小范围。您没有说是否应该为此服务器配置“客户端证书”(实际上是以Java privateKeyEntry形式的密钥和证书);如果服务器要求并且不正确,某些服务器可能认为这是一种攻击并且通过关闭而故意违反协议,即使他们正式发送警报也是如此。
或者,网络中的某些中间件,通常是防火墙或声称透明的代理,决定它不喜欢你的连接并强行关闭。你使用的代理是一个明显的嫌疑人;当您说“相同代码”适用于其他主机时,请确认您是否通过相同代理(不仅仅是代理)并使用HTTPS(不清晰HTTP)。如果不是这样,请尝试通过代理使用HTTPS测试其他主机(您不需要发送完整的SOAP请求,只需要GET / if)。如果可以的话,尝试在没有代理的情况下连接,或者尝试使用不同的代理,并通过代理将HTTP(而不是S)连接到主机(如果两者都支持清除),看看它们是否有效。
如果您不介意发布实际主机(但绝对不是任何身份验证凭据),其他人可以尝试。或者您可以访问www.ssllabs.com并要求他们测试服务器(不公布结果);这将尝试SSL / TLS连接的几个常见变体,并报告它看到的任何错误,以及任何安全漏洞。
答案 3 :(得分:8)
诊断问题的第一步是启动客户端 - 如果您自己运行服务器,则是服务器的私有测试实例 - 通过使用VM选项启动Java:
-Djavax.net.debug=all
另见https://blogs.oracle.com/java-platform-group/entry/diagnosing_tls_ssl_and_https
答案 4 :(得分: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 Cryptography Extension(JCE)Unlimited Strength Jurisdiction Policy Files ,因为默认情况下服务器只了解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
答案 5 :(得分:7)
我认为你错过了证书。
您可以尝试使用InstallCerts应用生成它们。在这里你可以看到如何使用它: https://github.com/escline/InstallCert
获得证书后,您需要将其放在jdk家中的安全目录下,例如:
C:\Program Files\Java\jdk1.6.0_45\jre\lib\security
让我知道它是否有效。
答案 6 :(得分:2)
我遇到了类似的问题,发现我遇到了错误的端口。修好港口后,事情很顺利。
答案 7 :(得分:1)
在我的情况下,我遇到了这个问题,因为我已经给服务器一个不存在的证书,因为配置文件中有拼写错误。服务器没有抛出异常,而是像往常一样继续向客户端发送空证书。所以可能值得检查以确保服务器提供正确的响应。
使用Jersey Client连接服务器时遇到此错误。我解决它的方法是调试库并看到它在尝试读取时确实收到了EOF。我也尝试使用网络浏览器进行连接并获得相同的结果。
只是在这里写这个,以防它最终帮助任何人。
答案 8 :(得分:1)
我使用Java 8运行我的应用程序,Java 8将安全证书带到其信任存储区。然后我切换到Java 7并将以下内容添加到VM选项中:
-Djavax.net.ssl.trustStore=C:\<....>\java8\jre\lib\security\cacerts
我只是指出了证书所在的位置。
答案 9 :(得分:1)
你可以在下面的代码中写下你当前的java程序
System.setProperty(“https.protocols”,“TLSv1.1”);
或
System.setProperty(“http.proxyHost”,“proxy.com”); System.setProperty(“http.proxyPort”,“911”);
答案 10 :(得分:1)
我在Java 1.6中遇到了这个问题。在Java 1.7下运行修复了我对问题的特殊演绎。我认为根本原因是我连接的服务器必须要求比1.6中更强的加密。
答案 11 :(得分:1)
感谢大家分享您的答案和示例。同样的独立程序通过小的更改为我工作,并添加下面的代码行。
在这种情况下,密钥库文件由webservice provider提供。
// 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");
答案 12 :(得分:0)
我遇到了同样的错误,但在我的情况下,它是由Intellij IDE中的DEBUG模式引起的。调试减慢了库的速度,然后服务器在握手阶段结束了通信。标准的“运行”非常有效。
答案 13 :(得分:0)
我曾经遇到过同样的问题。我认为这是因为URL
String xmlServerURL =“https://example.com/soap/WsRouter”;
检查它是否合适?
javax.net.ssl.SSLHandshakeException
是因为服务器因以下原因而无法连接到指定的网址 -
答案 14 :(得分:0)
我正在使用我在MacBook中使用Keychain导出的p12,但是,它在我的java-apns服务器代码上无效。我必须做的是使用我已经生成的pem键创建一个新的p12键,如here所述:
openssl pkcs12 -export -in your_app.pem -inkey your_key.pem -out your_app_key.p12
然后更新了新p12文件的路径,一切都运行良好。
答案 15 :(得分:0)
如何解决问题的方法是转到
设置
搜索 “网络”
选择“将IDEA常规代理设置用作默认Subversion”
答案 16 :(得分:0)
根据https://kb.informatica.com/solution/23/Pages/69/570664.aspx添加此属性有效
CryptoProtocolVersion = TLSv1.2
答案 17 :(得分:0)
使用TLSv1.2 ALERT: fatal, handshake_failure线程调试后获得的基数为previos answer,
-Djavax.net.debug = all
我去了https://www.ssllabs.com/,发现该Web服务器要求SSLv3连接于2015年6月弃用,而JDKu31 Release notes
弃用我在一行中编辑了$ {java_home} /jre/lib/security/java.security
jdk.tls.disabledAlgorithms = SSLv3,RC4,DES,MD5和RSA,DH密钥大小<1024,
EC keySize <224,3DES_EDE_CBC,anon,NULL
到
jdk.tls.disabledAlgorithms = RC4,DES,带有RSA的MD5,DH密钥大小<1024,
EC键大小<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 path building failed” and “unable to find valid certification path to requested target”
修复了使用java keytool安装证书的问题答案 18 :(得分:0)
我在指定 https url 并在同一个 url 中明确指定 http 端口(而不是 https 端口)时收到此错误。删除显式端口 :8080
为我解决了这个问题。
答案 19 :(得分:-1)
将证书添加到Java \ jdk \ jre \ lib \ security文件夹对我有用。如果您使用Chrome,请单击绿色灯泡[https://support.google.com/chrome/answer/95617?p=ui_security_indicator&rd=1]并将证书保存在安全文件夹中。
答案 20 :(得分:-3)
这就解决了我的问题。
如果您正在尝试使用调试器,请确保断点不在URL或URLConnection上,只需将断点放在BufferReader上或while循环中。
如果无效,请尝试使用apache库http://hc.apache.org/index.html。
没有SSL,不需要JDK更新,甚至不需要设置属性,只需简单的技巧:)