SSLHandshakeException:在 Java 6 -> 8 升级后收到致命警报:handshake_failure
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32208244/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
SSLHandshakeException: Received fatal alert: handshake_failure after Java 6 -> 8 upgrade
提问by Jesper Lehtinen
We've recently updated a project from Java 6 to Java 8 and now we've hit a brick wall regarding SSL handshake.
我们最近将一个项目从 Java 6 更新到 Java 8,现在我们遇到了关于 SSL 握手的砖墙。
The service layer uses a client to request and receive calls from a third party application. In the service layer, the keystore is initialized with
服务层使用客户端来请求和接收来自第三方应用程序的调用。在服务层,密钥库初始化为
System.setProperty("javax.net.ssl.trustStore", keyStoreFile);
System.setProperty("javax.net.ssl.trustStorePassword", keyStorePassword);
and injected via applicationContext.xml:
并通过 applicationContext.xml 注入:
<property name="keyStoreFile" value="/keystore/keystore.keystore" />
<property name="keyStorePassword" value="password" />
What's weird is: 1. this isn't a complete file path, obviously. 2. there are no keystores on this server (and it works regardless with Java 6).
奇怪的是: 1. 这显然不是完整的文件路径。2. 此服务器上没有密钥库(无论是否使用 Java 6,它都可以工作)。
The client is supposed to trust all certificates in case of errors:
如果出现错误,客户端应该信任所有证书:
/**
* Sets a trust manager that ignores the certificate chains. Use if the
* server has a certificate that can't be verified.
*
*/
private void trustHttpsCertificates() throws Exception {
try {
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
}};
// Ignore differences between given hostname and certificate hostname
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) { return true; }
};
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("TLSv1"); //$NON-NLS-1$
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(hv);
} catch (KeyManagementException e) {
String errorMsg = "client initialization error: " //$NON-NLS-1$
+ e.getMessage();
log.error(errorMsg);
throw new Exception(errorMsg, e);
}
}
SSLContext.getInstance("TLSv1"); used to be getInstance("SSL"); but I don't think SSL is supported on Java 8 any more, so I changed it to TLSv1. Might that be a problem?
SSLContext.getInstance("TLSv1"); 曾经是 getInstance("SSL"); 但我认为 Java 8 不再支持 SSL,所以我将其更改为 TLSv1。这可能是个问题吗?
Debug logs
调试日志
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
http-nio-9080-exec-6, setSoTimeout(0) called
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1.1
%% No cached client session
*** ClientHello, TLSv1.2
RandomCookie: GMT: 1423711122 bytes = { 237, 188, 53, 112, 79, 112, 248, 92, 164, 127, 178, 34, 205, 40, 245, 25, 77, 143, 116, 126, 203, 96, 61, 181, 114, 148, 66, 227 }
Session ID: {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods: { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA
***
[write] MD5 and SHA1 hashes: len = 237
0000: 01 00 00 E9 03 03 55 DC 1C 92 ED BC 35 70 4F 70 ......U.....5pOp
0010: F8 5C A4 7F B2 22 CD 28 F5 19 4D 8F 74 7E CB 60 .\...".(..M.t..`
0020: 3D B5 72 94 42 E3 00 00 64 C0 24 C0 28 00 3D C0 =.r.B...d.$.(.=.
0030: 26 C0 2A 00 6B 00 6A C0 0A C0 14 00 35 C0 05 C0 &.*.k.j.....5...
0040: 0F 00 39 00 38 C0 23 C0 27 00 3C C0 25 C0 29 00 ..9.8.#.'.<.%.).
0050: 67 00 40 C0 09 C0 13 00 2F C0 04 C0 0E 00 33 00 g.@...../.....3.
0060: 32 C0 2C C0 2B C0 30 00 9D C0 2E C0 32 00 9F 00 2.,.+.0.....2...
0070: A3 C0 2F 00 9C C0 2D C0 31 00 9E 00 A2 C0 08 C0 ../...-.1.......
0080: 12 00 0A C0 03 C0 0D 00 16 00 13 00 FF 01 00 00 ................
0090: 5C 00 0A 00 34 00 32 00 17 00 01 00 03 00 13 00 \...4.2.........
00A0: 15 00 06 00 07 00 09 00 0A 00 18 00 0B 00 0C 00 ................
00B0: 19 00 0D 00 0E 00 0F 00 10 00 11 00 02 00 12 00 ................
00C0: 04 00 05 00 14 00 08 00 16 00 0B 00 02 01 00 00 ................
00D0: 0D 00 1A 00 18 06 03 06 01 05 03 05 01 04 03 04 ................
00E0: 01 03 03 03 01 02 03 02 01 02 02 01 01 .............
http-nio-9080-exec-6, WRITE: TLSv1.2 Handshake, length = 237
[Raw write]: length = 242
0000: 16 03 03 00 ED 01 00 00 E9 03 03 55 DC 1C 92 ED ...........U....
0010: BC 35 70 4F 70 F8 5C A4 7F B2 22 CD 28 F5 19 4D .5pOp.\...".(..M
0020: 8F 74 7E CB 60 3D B5 72 94 42 E3 00 00 64 C0 24 .t..`=.r.B...d.$
0030: C0 28 00 3D C0 26 C0 2A 00 6B 00 6A C0 0A C0 14 .(.=.&.*.k.j....
0040: 00 35 C0 05 C0 0F 00 39 00 38 C0 23 C0 27 00 3C .5.....9.8.#.'.<
0050: C0 25 C0 29 00 67 00 40 C0 09 C0 13 00 2F C0 04 .%.).g.@...../..
0060: C0 0E 00 33 00 32 C0 2C C0 2B C0 30 00 9D C0 2E ...3.2.,.+.0....
0070: C0 32 00 9F 00 A3 C0 2F 00 9C C0 2D C0 31 00 9E .2...../...-.1..
0080: 00 A2 C0 08 C0 12 00 0A C0 03 C0 0D 00 16 00 13 ................
0090: 00 FF 01 00 00 5C 00 0A 00 34 00 32 00 17 00 01 .....\...4.2....
00A0: 00 03 00 13 00 15 00 06 00 07 00 09 00 0A 00 18 ................
00B0: 00 0B 00 0C 00 19 00 0D 00 0E 00 0F 00 10 00 11 ................
00C0: 00 02 00 12 00 04 00 05 00 14 00 08 00 16 00 0B ................
00D0: 00 02 01 00 00 0D 00 1A 00 18 06 03 06 01 05 03 ................
00E0: 05 01 04 03 04 01 03 03 03 01 02 03 02 01 02 02 ................
00F0: 01 01 ..
[Raw read]: length = 5
0000: 15 03 01 00 02 .....
[Raw read]: length = 2
0000: 02 28 .(
http-nio-9080-exec-6, READ: TLSv1 Alert, length = 2
http-nio-9080-exec-6, RECV TLSv1.2 ALERT: fatal, handshake_failure
http-nio-9080-exec-6, called closeSocket()
http-nio-9080-exec-6, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
[2015-08-25 09:43:14:014 CEST] ERROR [http-nio-9080-exec-6][] snod.SnodPKClient: Failed to request and read response from snod: Received fatal alert: handshake_failure
[2015-08-25 09:43:14:014 CEST] ERROR [http-nio-9080-exec-6][] snod.SnodPKClient: Failed to request SNOD information: Failed to request and read response from snod: Received fatal alert: handshake_failure
[2015-08-25 09:43:14:014 CEST] WARN [http-nio-9080-exec-6][]
snod.SnodException: Failed to request and read response from snod: Received fatal alert: handshake_failure
at xx.xx.SnodClient.queryService(SnodClient.java:151)
at xx.xx.SnodPKClient.fetchPerson(SnodPKClient.java:169)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:68)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:168)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy81.pop(Unknown Source)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:711)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor.proceedWithInvocation(TransactionInterceptor.java:98)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:68)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)
at xx.xx.Service$$EnhancerBySpringCGLIB$$f31df72a.get(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:711)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:68)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.ws.server.endpoint.MethodEndpoint.invoke(MethodEndpoint.java:134)
at org.springframework.ws.server.endpoint.adapter.MarshallingMethodEndpointAdapter.invokeInternal(MarshallingMethodEndpointAdapter.java:141)
at org.springframework.ws.server.endpoint.adapter.AbstractMethodEndpointAdapter.invoke(AbstractMethodEndpointAdapter.java:55)
at org.springframework.ws.server.MessageDispatcher.dispatch(MessageDispatcher.java:236)
at org.springframework.ws.server.MessageDispatcher.receive(MessageDispatcher.java:176)
at org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:89)
at org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle(WebServiceMessageReceiverHandlerAdapter.java:61)
at org.springframework.ws.transport.http.MessageDispatcherServlet.doService(MessageDispatcherServlet.java:293)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:617)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2023)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1125)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
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.getInputStream0(HttpURLConnection.java:1512)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1440)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:338)
at xx.xx.SnodClient.httpRequestCheck(SnodClient.java:339)
at xx.xx.SnodClient.queryService(SnodClient.java:140)
... 97 more
Thoughts
想法
There are mainly two things that stand out compared to the old version with Java 6:
与 Java 6 的旧版本相比,主要有两点突出:
- In the logs for the old verison, when a successful attempt is made, it clealy presents the correct certificate:
- 在旧版本的日志中,当成功尝试时,它清楚地提供了正确的证书:
certificate
证书
http-9080-1, READ: TLSv1 Handshake, length = 1375
*** Certificate chain
chain [0] = [
[
Version: V3
Subject: CN=Janus, OU=Janus Snod Server, O=Media Communications Eur AB (publ), L=Stockholm, ST=Stockholms Lan, C=SE
Signature Algorithm: MD5withRSA, OID = 1.2.840.113549.1.1.4
Key: Sun RSA public key, 1024 bits
modulus: 154938606312449178696821964101723049260345574724508497470358703346529895346419731715548240827139735285491863427521115606880526282651126615234990610880260841123741428540874639484268039421250487320597319639022576052540499319669985035693206002281790184516249920955711188003336296074244648385317324358551590420109
public exponent: 65537
Validity: [From: Wed May 26 14:31:31 CEST 1999,
To: Thu May 25 14:31:31 CEST 2000]
Issuer: CN=SnodServer25, OU=SnodServer, O=Media Communications Eur AB (publ), L=Stockholm, ST=Stockholms Lan, C=SE
SerialNumber: [ 01]
]
Algorithm: [MD5withRSA]
This doesn't happen in the new Java 8 version.
这在新的 Java 8 版本中不会发生。
- This part:
- 这部分:
TLSv1 vs TLSv1.2?
TLSv1 与 TLSv1.2?
http-nio-9080-exec-6, READ: TLSv1 Alert, length = 2
http-nio-9080-exec-6, RECV TLSv1.2 ALERT: fatal, handshake_failure
Is it saying I'm trying to connect with TLSv1.2? Or TLSv1? And it's not accepted? I don't really understand. Is there a way to find out what TLS versions are accepted by the server?
是不是说我正在尝试连接 TLSv1.2?还是 TLSv1?并且不被接受?我真的不明白。有没有办法找出服务器接受哪些 TLS 版本?
I've tried adding flags to startup:
我试过在启动时添加标志:
-Dhttps.protocols=TLSv1
-Ddeployment.security.TLSv1=true
-Djavax.net.ssl.keyStore=C:\keystore\keystore.keystore
-Djavax.net.ssl.keyStorePassword=password
-Djavax.net.ssl.trustStore=C:\keystore\keystore.keystore
-Djavax.net.ssl.trustStorePassword=password
Also adding a keystore Manager programmatically:
还以编程方式添加密钥库管理器:
KeyStore ks = KeyStore.getInstance("JKS");
InputStream ksIs = new FileInputStream("c:/srs/keystore/keystore.keystore");
try {
ks.load(ksIs, password.toCharArray());
} catch (CertificateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ksIs != null) {
try {
ksIs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, password.toCharArray());
and then initializing SSLContext with that:
然后用它初始化 SSLContext:
sc.init(kmf.getKeyManagers(), trustAllCerts, new SecureRandom());
but the problem persists. Help, anyone?
但问题仍然存在。帮助,有人吗?
采纳答案by Jesper Lehtinen
Alright, so now we've got it working now. I'll post the answer here in case someone might need it some day.
好的,现在我们已经让它工作了。我会在这里发布答案,以防有一天有人需要它。
I've tried quite a few things, so I'm not totally sure what actually needed to be done, but here are some things:
我已经尝试了很多事情,所以我不完全确定实际需要做什么,但这里有一些事情:
setting
环境
-Dhttps.protocols=SSLv3,TLSv1,SSLv2Hello
led to the certificate being presented in the javax.net.debug
logs, but we were still getting SSLHandshakeException
. It seems like the only cipher the server would accept was SSL_RSA_WITH_RC4_128_MD5
. This was not picked automatically by our client (still no idea why). This led to adding
导致证书出现在javax.net.debug
日志中,但我们仍然得到SSLHandshakeException
. 似乎服务器接受的唯一密码是SSL_RSA_WITH_RC4_128_MD5
. 这不是我们的客户自动选择的(仍然不知道为什么)。这导致添加
-Dhttps.cipherSuites=SSL_RSA_WITH_RC4_128_MD5
and also adding
并添加
socket.setEnabledCipherSuites(new String[] {"SSL_RSA_WITH_RC4_128_MD5"});
in code. Apparently, restricting the available cipher suites that the client can use led it to working.
在代码中。显然,限制客户端可以使用的可用密码套件使其正常工作。
The jre/lib/security/java.security
file also had to be updated with:
该jre/lib/security/java.security
文件还必须更新为:
- removing
SSLv3
fromjdk.tls.disabledAlgorithms
- adding
SSL_RSA_WITH_RC4_128_MD5
tojdk.tls.legacyAlgorithms
- 除去
SSLv3
从jdk.tls.disabledAlgorithms
- 添加
SSL_RSA_WITH_RC4_128_MD5
到jdk.tls.legacyAlgorithms
This is probably not recommended for production servers, since a) SSLv3 is obsolete, and b) the cipher is very old and outdated, but in this case security is not a huge concern (internal application use).
这可能不推荐用于生产服务器,因为 a) SSLv3 已过时,并且 b) 密码非常陈旧且过时,但在这种情况下,安全性不是一个大问题(内部应用程序使用)。
These posts were also helpful to me:
这些帖子对我也有帮助:
回答by Steffen Ullrich
My guess is that your server is too broken to deal properly with TLS 1.2 handshakes. Usually a server which does not understand TLS 1.2 should reply with the best version it can but your server does not.
我的猜测是你的服务器太坏了,无法正确处理 TLS 1.2 握手。通常,不理解 TLS 1.2 的服务器应该回复它可以使用的最佳版本,但您的服务器不会。
Broken servers like this exists and browsers try to work around these by retrying with a lower TLS version. Outside of browsers these retries are not common so these clients simply fail.
像这样的损坏的服务器存在,浏览器尝试通过使用较低的 TLS 版本重试来解决这些问题。在浏览器之外,这些重试并不常见,因此这些客户端只会失败。
While I cannot say for sure that the server is broken the certificate which expired 15 years ago and was signed with the long broken MD5 algorithm suggest that you have to do with a very old and neglected installation. So chances are high that it never occurred to the developers of the original server that something like TLS 1.2 might ever exist or that the it croaks on one of the TLS extensions used in the TLS 1.2 handshake.
虽然我不能确定服务器是否损坏,但 15 年前过期并使用长期损坏的 MD5 算法签名的证书表明您必须使用非常古老且被忽视的安装。因此,原始服务器的开发人员很可能从未想过可能存在 TLS 1.2 之类的东西,或者它在 TLS 1.2 握手中使用的 TLS 扩展之一上发出嘶嘶声。
Since this issue is not related to the validation of the certificate all attempts to fix the issue by fiddling in the area of validation are useless. You might have more success if you enforce the use of TLS 1.1 or TLS 1.1 instead of TLS 1.2. You might try to do this with the -Dhttps.protocols=TLSv1,TLSv1.1
or -Dhttps.protocols=TLSv1
settings.
由于此问题与证书的验证无关,因此通过在验证区域中摆弄来解决问题的所有尝试都是无用的。如果您强制使用 TLS 1.1 或 TLS 1.1 而不是 TLS 1.2,您可能会取得更大的成功。您可以尝试使用-Dhttps.protocols=TLSv1,TLSv1.1
或-Dhttps.protocols=TLSv1
设置执行此操作。
回答by chirag
String testURL = "https://api.chargeio.com/status";
SSLContext sslcontext = SSLContext.getInstance("TLSv1.2");
sslcontext.init(null, null, null);
try {
SSLConnectionSocketFactory socketFactory = new
SSLConnectionSocketFactory(sslcontext,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); // Socket
HttpClient client =
HttpClients.custom().setSSLSocketFactory(socketFactory).build();
HttpGet httpget = new HttpGet(testURL);
HttpResponse response = client.execute(httpget);
System.out.println(EntityUtils.toString(response.getEntity()));
System.out.println("Response Code (Apache): " + response.getStatusLine().getStatusCode());
} catch (Exception e) {
System.err.println("HttpsURLConnection Failed");
e.printStackTrace();
}