Java9 HttpClient SSLHandshakeException

时间:2018-01-21 09:35:01

标签: java ssl tls1.2 java-9 java-http-client

我正在尝试从Java 9测试新的HttpClient。出于测试目的,我使用的是https://jsonplaceholder.typicode.com提供的api。但是,我收到握手异常,不知道原因。

我正在运行的代码:

 private final String TEST_URI = "https://jsonplaceholder.typicode.com/posts";

    @Test
    public void shouldReturnStatusOKWhenSendGetRequest() throws IOException, InterruptedException, URISyntaxException {
        HttpRequest request = HttpRequest.newBuilder()
                .uri(new URI(TEST_URI))
                .GET()
                .build();
        HttpResponse<String> response = HttpClient.newHttpClient()
                .send(request, HttpResponse.BodyHandler.asString());
        assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK));
    }

我收到一个例外:

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at java.base/sun.security.ssl.Alerts.getSSLException(Alerts.java:198)
    at java.base/sun.security.ssl.Alerts.getSSLException(Alerts.java:159)
    at java.base/sun.security.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1905)
    at java.base/sun.security.ssl.SSLEngineImpl.processInputRecord(SSLEngineImpl.java:1140)
    at java.base/sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1020)
    at java.base/sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:902)
    at java.base/sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:680)
    at java.base/javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:626)
    at jdk.incubator.httpclient/jdk.incubator.http.AsyncSSLDelegate.unwrapBuffer(AsyncSSLDelegate.java:476)
    at jdk.incubator.httpclient/jdk.incubator.http.AsyncSSLDelegate.handshakeReceiveAndUnWrap(AsyncSSLDelegate.java:395)
    at jdk.incubator.httpclient/jdk.incubator.http.AsyncSSLDelegate.doHandshakeImpl(AsyncSSLDelegate.java:294)
    at jdk.incubator.httpclient/jdk.incubator.http.AsyncSSLDelegate.doHandshakeNow(AsyncSSLDelegate.java:262)
    at jdk.incubator.httpclient/jdk.incubator.http.AsyncSSLDelegate.connect(AsyncSSLDelegate.java:233)
    at jdk.incubator.httpclient/jdk.incubator.http.AsyncSSLConnection.connect(AsyncSSLConnection.java:78)
    at jdk.incubator.httpclient/jdk.incubator.http.Http2Connection.<init>(Http2Connection.java:272)
    at jdk.incubator.httpclient/jdk.incubator.http.Http2ClientImpl.getConnectionFor(Http2ClientImpl.java:108)
    at jdk.incubator.httpclient/jdk.incubator.http.ExchangeImpl.get(ExchangeImpl.java:86)
    at jdk.incubator.httpclient/jdk.incubator.http.Exchange.establishExchange(Exchange.java:257)
    at jdk.incubator.httpclient/jdk.incubator.http.Exchange.responseImpl0(Exchange.java:268)
    at jdk.incubator.httpclient/jdk.incubator.http.Exchange.responseImpl(Exchange.java:245)
    at jdk.incubator.httpclient/jdk.incubator.http.Exchange.response(Exchange.java:121)
    at jdk.incubator.httpclient/jdk.incubator.http.MultiExchange.response(MultiExchange.java:154)
    at jdk.incubator.httpclient/jdk.incubator.http.HttpClientImpl.send(HttpClientImpl.java:234)
    at com.us.HttpRequestTest.shouldReturnStatusOKWhenSendGetRequest(HttpRequestTest.java:35)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

我启用了参数 -Djavax.net.debug = all 的详细调试消息,我收到的日志是:

Using SSLEngineImpl.
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
Ignoring obsoleted cipher suite: SSL_RSA_WITH_DES_CBC_SHA
Ignoring obsoleted cipher suite: SSL_DHE_RSA_WITH_DES_CBC_SHA
Ignoring obsoleted cipher suite: SSL_DHE_DSS_WITH_DES_CBC_SHA
Ignoring obsoleted cipher suite: SSL_DH_anon_WITH_DES_CBC_SHA
Ignoring obsoleted cipher suite: SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
Ignoring obsoleted cipher suite: SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
Ignoring obsoleted cipher suite: SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
Ignoring obsoleted cipher suite: SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
Ignoring obsoleted cipher suite: TLS_KRB5_WITH_DES_CBC_SHA
Ignoring obsoleted cipher suite: TLS_KRB5_WITH_DES_CBC_MD5
Ignoring obsoleted cipher suite: TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA
Ignoring obsoleted cipher suite: TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5
%% No cached client session
update handshake state: client_hello[1]
upcoming handshake states: server_hello[2]
*** ClientHello, TLSv1.2
RandomCookie:  random_bytes = {9C CA 88 05 6E 9C 04 57 09 CB 84 92 A4 1D 83 2A 1F E7 34 A7 AB E2 E4 9C 7F 5B 0F 95 04 B0 A7 C5}
Session ID:  {}
Cipher Suites: [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_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_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, TLS_DH_anon_WITH_AES_256_GCM_SHA384, TLS_DH_anon_WITH_AES_128_GCM_SHA256, TLS_DH_anon_WITH_AES_256_CBC_SHA256, TLS_ECDH_anon_WITH_AES_256_CBC_SHA, TLS_DH_anon_WITH_AES_256_CBC_SHA, TLS_DH_anon_WITH_AES_128_CBC_SHA256, TLS_ECDH_anon_WITH_AES_128_CBC_SHA, TLS_DH_anon_WITH_AES_128_CBC_SHA, TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, TLS_RSA_WITH_NULL_SHA256, TLS_ECDHE_ECDSA_WITH_NULL_SHA, TLS_ECDHE_RSA_WITH_NULL_SHA, SSL_RSA_WITH_NULL_SHA, TLS_ECDH_ECDSA_WITH_NULL_SHA, TLS_ECDH_RSA_WITH_NULL_SHA, TLS_ECDH_anon_WITH_NULL_SHA, SSL_RSA_WITH_NULL_MD5, TLS_KRB5_WITH_3DES_EDE_CBC_SHA, TLS_KRB5_WITH_3DES_EDE_CBC_MD5]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, secp384r1, secp521r1, sect283k1, sect283r1, sect409k1, sect409r1, sect571k1, sect571r1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA224withECDSA, SHA224withRSA, SHA224withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA
Extension status_request_v2
CertStatusReqItemV2: ocsp_multi, OCSPStatusRequest
    ResponderIds: <EMPTY>
    Extensions: <EMPTY>
CertStatusReqItemV2: ocsp, OCSPStatusRequest
    ResponderIds: <EMPTY>
    Extensions: <EMPTY>
Extension status_request: ocsp, OCSPStatusRequest
    ResponderIds: <EMPTY>
    Extensions: <EMPTY>
Extension application_layer_protocol_negotiation, protocol names: [h2][http/1.1]
main, WRITE: TLSv1.2 Handshake, length = 296
[Raw write]: length = 301
0000: 16 03 03 01 28 01 00 01   24 03 03 9C CA 88 05 6E  ....(...$......n
0010: 9C 04 57 09 CB 84 92 A4   1D 83 2A 1F E7 34 A7 AB  ..W.......*..4..
0020: E2 E4 9C 7F 5B 0F 95 04   B0 A7 C5 00 00 8C C0 2C  ....[..........,
0030: C0 2B C0 30 00 9D C0 2E   C0 32 00 9F 00 A3 C0 2F  .+.0.....2...../
0040: 00 9C C0 2D C0 31 00 9E   00 A2 C0 24 C0 28 00 3D  ...-.1.....$.(.=
0050: C0 26 C0 2A 00 6B 00 6A   C0 0A C0 14 00 35 C0 05  .&.*.k.j.....5..
0060: C0 0F 00 39 00 38 C0 23   C0 27 00 3C C0 25 C0 29  ...9.8.#.'.<.%.)
0070: 00 67 00 40 C0 09 C0 13   00 2F C0 04 C0 0E 00 33  .g.@...../.....3
0080: 00 32 C0 08 C0 12 00 0A   C0 03 C0 0D 00 16 00 13  .2..............
0090: 00 FF 00 A7 00 A6 00 6D   C0 19 00 3A 00 6C C0 18  .......m...:.l..
00A0: 00 34 C0 17 00 1B 00 3B   C0 06 C0 10 00 02 C0 01  .4.....;........
00B0: C0 0B C0 15 00 01 00 1F   00 23 01 00 00 6F 00 0A  .........#...o..
00C0: 00 16 00 14 00 17 00 18   00 19 00 09 00 0A 00 0B  ................
00D0: 00 0C 00 0D 00 0E 00 16   00 0B 00 02 01 00 00 0D  ................
00E0: 00 1C 00 1A 06 03 06 01   05 03 05 01 04 03 04 01  ................
00F0: 04 02 03 03 03 01 03 02   02 03 02 01 02 02 00 11  ................
0100: 00 10 00 0E 02 00 04 00   00 00 00 01 00 04 00 00  ................
0110: 00 00 00 05 00 05 01 00   00 00 00 00 10 00 0E 00  ................
0120: 0C 02 68 32 08 68 74 74   70 2F 31 2E 31           ..h2.http/1.1
[Raw read]: length = 7
0000: 15 03 01 00 02 02 28                               ......(
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1.2 ALERT:  fatal, handshake_failure
main, fatal error: 40: General SSLEngine problem
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
main, fatal: engine already closed.  Rethrowing javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

1 个答案:

答案 0 :(得分:5)

调试日志显示ClientHello中不包含server_name扩展名(SNI)。但是,根据SSLLabs,该站点在没有SNI的情况下失败。

这似乎是Java 9中此API的已知问题。请参阅错误报告TLS SNI in new Java 9 client is not available以及可能的解决方法Glorious hack to use Java 9 HttpClient with servers enforcing SNI Raw