RestTemplate SSL握手失败 - 丢弃连接

时间:2018-01-24 17:29:46

标签: java spring ssl resttemplate

我尝试从Spring 4应用程序连接到API rest,我使用jdk1.6.0_121(它支持TLSv1.2)和JCE 1.6,在开发代码中我接受所有证书。 我知道在这种情况下存在2个可能的错误

  • 连接问题
  • 关闭端口

但是这个选项被丢弃了,因为我使用Postman从我的本地机器调用API rest并且工作正常,但是从测试服务器不起作用。

@Configuration
public class RestTemplateConfig {

    private static final int TIMEOUT = 20000;
    private static final Logger LOGGER = Logger.getLogger(RestTemplateConfig.class);

    @Bean
    public RestTemplate restTemplate() {
        try {
            TrustManager tm = new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }

                public void checkServerTrusted(X509Certificate[] chain, String authType) {
                    LOGGER.info("Auto-trusted server certificate chain");
                }

                public void checkClientTrusted(X509Certificate[] chain, String authType) {
                    LOGGER.info("Auto-trusted client certificate chain");
                }
            };
            SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
            sslContext.init(null, new TrustManager[]{tm}, new SecureRandom());
            SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, new String[]{"TLSv1.2"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
            CloseableHttpClient httpClient = HttpClients.custom()
                    .setSSLSocketFactory(csf)
                    .build();
            HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
            requestFactory.setConnectTimeout(TIMEOUT);
            requestFactory.setReadTimeout(TIMEOUT);
            requestFactory.setHttpClient(httpClient);
            return new RestTemplate(requestFactory);
        } catch (Exception e) {
            LOGGER.error("No se pudo inicializar configuracion SSL ", e);
        }
        return null;
    }
}

来自服务器的StackTrace:

[24/01/2018 13:14:55] [DEBUG] [JSID=] [org.apache.http.client.protocol.RequestAddCookies]:123 - CookieSpec selected: default
[24/01/2018 13:14:55] [DEBUG] [JSID=] [org.apache.http.client.protocol.RequestAuthCache]:77 - Auth cache not set in the context
[24/01/2018 13:14:55] [DEBUG] [JSID=] [org.apache.http.impl.conn.PoolingHttpClientConnectionManager]:265 - Connection request: [route: {s}->https://api.xxx.tech:443][total kept alive: 0; route allocated: 0 of 2; total allocated: 0 of 20]
[24/01/2018 13:14:55] [DEBUG] [JSID=] [org.apache.http.impl.conn.PoolingHttpClientConnectionManager]:309 - Connection leased: [id: 0][route: {s}->https://api.xxx.tech:443][total kept alive: 0; route allocated: 1 of 2; total allocated: 1 of 20]
[24/01/2018 13:14:55] [DEBUG] [JSID=] [org.apache.http.impl.execchain.MainClientExec]:235 - Opening connection {s}->https://api.xxx.tech:443
[24/01/2018 13:14:56] [DEBUG] [JSID=] [org.apache.http.impl.conn.DefaultHttpClientConnectionOperator]:139 - Connecting to api.xxx.tech/40.123.54.233:443
[24/01/2018 13:14:56] [DEBUG] [JSID=] [org.apache.http.conn.ssl.SSLConnectionSocketFactory]:337 - Connecting socket to api.xxx.tech/40.123.54.233:443 with timeout 20000
[24/01/2018 13:14:56] [DEBUG] [JSID=] [org.apache.http.conn.ssl.SSLConnectionSocketFactory]:390 - Enabled protocols: [TLSv1.2]
[24/01/2018 13:14:56] [DEBUG] [JSID=] [org.apache.http.conn.ssl.SSLConnectionSocketFactory]:391 - Enabled cipher suites:[TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_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]
[24/01/2018 13:14:56] [DEBUG] [JSID=] [org.apache.http.conn.ssl.SSLConnectionSocketFactory]:395 - Starting handshake
[24/01/2018 13:14:56] [DEBUG] [JSID=] [org.apache.http.impl.conn.DefaultManagedHttpClientConnection]:96 - http-outgoing-0: Shutdown connection
[24/01/2018 13:14:56] [DEBUG] [JSID=] [org.apache.http.impl.execchain.MainClientExec]:129 - Connection discarded
[24/01/2018 13:14:56] [DEBUG] [JSID=] [org.apache.http.impl.conn.PoolingHttpClientConnectionManager]:348 - Connection released: [id: 0][route: {s}->https://api.xxx.tech:443][total kept alive: 0; route allocated: 0 of 2; total allocated: 0 of 20]
[24/01/2018 13:14:56] [ERROR] [JSID=] [com.falabella.lib.shared.kong.connector.service.PaymentServiceImpl]:65 - UPS! 
org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://api.xxx.tech/sso/oauth2/v2/token": Received fatal alert: handshake_failure; nested exception is javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:666)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
    at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:380)
    at com.falabella.lib.shared.kong.connector.service.PaymentServiceImpl.initPayment(PaymentServiceImpl.java:39)
    at com.falabella.lib.shared.kong.connector.web.controller.PaymentController.initPayment(PaymentController.java:23)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:301)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:184)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3750)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3714)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2283)
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2182)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1491)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:263)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:172)
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:134)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1970)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1077)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1323)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1350)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1334)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:396)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:355)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:373)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:381)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:237)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
    at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:89)
    at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
    at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:652)
    ... 34 more

从服务器我获得使用Openssl openssl s_client -showcerts -connect api.sandbox.connect.fif.tech:443的证书,我得到它。

CONNECTED(00000003)
depth=0 C = US, ST = California, L = San Francisco, O = Kong, OU = IT Department, CN = localhost
verify error:num=18:self signed certificate
verify return:1
depth=0 C = US, ST = California, L = San Francisco, O = Kong, OU = IT Department, CN = localhost
verify return:1
---
Certificate chain
 0 s:/C=US/ST=California/L=San Francisco/O=Kong/OU=IT Department/CN=localhost
   i:/C=US/ST=California/L=San Francisco/O=Kong/OU=IT Department/CN=localhost
-----BEGIN CERTIFICATE-----
MIIDZjCCAk4CCQDdxMEwqGHAxjANBgkqhkiG9w0BAQsFADB1MQswCQYDVQQGEwJV
UzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEN
MAsGA1UECgwES29uZzEWMBQGA1UECwwNSVQgRGVwYXJ0bWVudDESMBAGA1UEAwwJ
bG9jYWxob3N0MB4XDTE4MDExMTIwMjMyNVoXDTE4MDIxMDIwMjMyNVowdTELMAkG
A1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFu
Z6pX+6wFS4pjaZLPchrLBrcLONU/y2wOjWM2HwA76s1JEjPoe2qzesTqmDLu5Dv3
9bzPsNZU6NG/yBVBolalb3sCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAdQQdzir2
vbVeQnJiw5JxidbGGJdPtuYqUJGuuNaZxgDjHYDBwDxUOjF2+zwWeFtoW/kTxdGL
QGxY1I7Bqx3LTTzRO3obulKburBjwZNIW7pRD+8pc7c1DhuijRWzqk93edCQ2U0P
1B6g8gQnn0ZPyrkh8FlH7hVk28HeOlfxsA20Ui1MZPFjwRFgvkzBVejmx4Ywr+xv
nMlkS5qD4K1n8qzS9jcgGN75OQZqck68qkQ53Mg16Ozw88ncpeW0S7pKEehwZzQO
xv+QVL1PuWBQwReq+8W/45jLtasP8D/gX9PfQUxFRNvSp/bDWbAhUBhvLrKLBk4V
76wBbmi4cjZ62Q==
-----END CERTIFICATE-----
---
Server certificate
subject=/C=US/ST=California/L=San Francisco/O=Kong/OU=IT Department/CN=localhost
issuer=/C=US/ST=California/L=San Francisco/O=Kong/OU=IT Department/CN=localhost
---
No client certificate CA names sent
---
SSL handshake has read 1549 bytes and written 389 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: 00EC98B11D95F3B5987FF48CEF594588D
    Session-ID-ctx: 
    Master-Key: D2D3C1BB29CEDD0562EA20B0D82FC5E2A947
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    TLS session ticket lifetime hint: 600 (seconds)
    TLS session ticket:
    0000 - 81 c7 ac 9c 06 1e 09 7c-8c a5 45 ec 7c 1b 7a 2b   .......|..E.|.z+
    0010 - df 4b a0 1c a1 7d 1c f6-50 26 57 74 0c 1c a4 85   .K...},.P&Wt....
    0020 - 75 a4 07 65 1d f8 08 9d-2a 50 cd 40 66 c5 32 21   u..e..H.*P.@f.2!
    0030 - 56 d2 8d 1e 08 f8 07 e6-cc 55 f9 85 1b b3 0c 40   V.....G..U.....@
    0040 - 39 e8 9b 60 38 3e 19 62-da 55 7a 3c 8b 66 dd 91   9..`8>.b.Uz<.f..
    0050 - 03 d1 c8 2b 90 35 93 43-1f 7f 06 61 e0 dc 5d 1e   ...+.5.C...a..].
    0060 - 90 da e3 b8 1b 72 a2 46-37 20 36 96 ac 1b f5 d6   .....r.F7 6.....
    0070 - 81 14 75 d8 e0 ce 8b 6a-55 ec 27 e2 91 b3 2d ed   ..u....jU.'...-.
    0080 - d2 63 d8 c1 52 c6 07 58-38 ff f1 53 c5 2b d6 ff   .c..R..X8..S.+..
    0090 - 83 5a 53 5e 10 f5 54 75-7d 94 84 64 33 bb 13 33   .ZS^..Tu}..d3..3
    00a0 - cc c0 72 e6 ba 11 d3 4f-5a 6b 4a 5a 17 cb 32 54   ..r....OZkJZ..2T

    Start Time: 1516811974
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---
closed

EDITED

该应用程序安装在weblogic服务器10.3.6.0中。

2 个答案:

答案 0 :(得分:0)

jdk1.6.0_121 对 TLS 1.2 的支持有问题(效果不好),我尝试使用 Bouncy Castle 库(添加对 TLS 1.2 的支持)但有很多性能问题,最后是解决这个问题的唯一方法已更新至 JDK 1.7(原生支持 TSL 1.2)

答案 1 :(得分:0)

日志显示 https://api.xxx.tech/sso/oauth2/v2/token 证书的 CN 是 localhost - 尝试将证书中的 CN 修改为 api.xxx.tech

如果您登录该框并且可以向 https://localhost/sso/oauth2/v2/token 发出相同的请求 - 您可能不会看到错误,因为主机名将与证书 CN 匹配

您还可以为主题备用名称 (SAN) 添加 X509 条目,您可以在其中指定主题备用名称 DNS: localhostIP: 127.0.0.1