【问题标题】:javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure java 1.7_45javax.net.ssl.SSLHandshakeException:收到致命警报:handshake_failure java 1.7_45
【发布时间】:2019-05-09 07:49:35
【问题描述】:

我有一个 https 网页,我需要访问并获取一些文件,我正在使用 Java 1.7_45 和 apache httpclient 4.5.1 执行客户端请求时出现错误(如果我更改为 Java 8 它可以工作,但我无法将其更改为 Java 8):

我尝试了我在互联网上找到的所有内容 添加这些 VM 参数

-Dhttps.protocols=SSLv2Hello,SSLv2,SSLv3,TLSv1.1,TLSv1.2
-Djdk.tls.client.protocols=TLSv1.1,TLSv1.2
-Ddeployment.security.SSLv2Hello=false 
-Ddeployment.security.SSLv3=false 
-Ddeployment.security.TLSv1=false 
-Ddeployment.security.TLSv1.1=true 
-Ddeployment.security.TLSv1.2=true

更改文件夹 jre/lib/security 上的 jars

有趣的是错误显示java正在使用TLSv1但服务器不接受,我相信这就是错误的原因,但我尝试了一切来改变它。


    main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
            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:1979)
            at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1086)
            at
            sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1332)
            at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1359)
            at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1343)
            at
            org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:394)
            at
            org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353)
            at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:134)
            at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
            at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380)
            at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
            at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
            at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
            at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
            at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
            at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)

我得到错误的块代码基本上是:


HttpGet httpGetRequest = new HttpGet(uri);
CloseableHttpClient client = HttpClients.createDefault();
CloseableHttpResponse httpResponse = null;
httpResponse = client.execute(httpGetRequest);

调试模式的结果是


    keyStore is : 
        keyStore type is : jks
        keyStore provider is : 
        init keystore
        init keymanager of type SunX509
        trustStore is: C:\Program Files\Java\jdk1.7.0_45\jre\lib\security\cacerts
        trustStore type is : jks
        trustStore provider is : 
        init truststore

        trigger seeding of SecureRandom
        done seeding SecureRandom

        Received fatal alert: handshake_failure
        Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
        Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
        Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
        Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
        Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
        Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
        Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
        Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
        Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
        Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
        Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
        Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
        Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
        Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256
        main, setSoTimeout(0) called
        Allow unsafe renegotiation: false
        Allow legacy hello messages: true
        Is initial handshake: true
        Is secure renegotiation: false
        %% No cached client session
        *** ClientHello, TLSv1
        RandomCookie:  GMT: 1540543037 bytes = { 231, 49, 252, 97, 250, 248, 100, 42, 169, 55, 229, 211, 3, 60, 228, 9, 116, 240, 119, 7, 189, 29, 9, 164, 233, 49, 92, 71 }
        Session ID:  {}
        Cipher Suites: [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_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_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_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, SSL_RSA_WITH_RC4_128_MD5, 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 server_name, server_name: [host_name: services.swpc.noaa.gov]
        ***
        main, WRITE: TLSv1 Handshake, length = 194
        main, READ: TLSv1 Alert, length = 2
        main, RECV TLSv1 ALERT:  fatal, handshake_failure
        main, called closeSocket()
        main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
        main, called close()enter code here
        main, called closeInternal(true)

【问题讨论】:

    标签: java https java-7 handshake apache-httpcomponents


    【解决方案1】:

    我解决了这个问题,但使用了这个 sn-p 代码

    if (hostType.getProtocol().equals(Protocol.HTTPS)) {
    
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(SSLContexts.createDefault(),
                new String[] { SSL_VERSION }, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
        client = HttpClients.custom().setSSLSocketFactory(sslsf).build();
    }
    

    【讨论】:

      【解决方案2】:

      Java 8 默认支持TLSv1.2,很可能您调用的 url 的服务器正在使用TLSv1.2。虽然 Java 7 支持 TLSv1.2,但 TLSv1.0 是此 Java 版本的默认值。要在 Java 7 中使用 TLSv1.2,您确实必须设置 vm 属性 -Djdk.tls.client.protocols=TLSv1.2。然而,系统属性jdk.tls.client.protocols 是从 Java 1.7.0_95 引入的。因此,您的选择是使用 Java 8 或升级到支持 jdk.tls.client.protocols 的 Java 7 版本。

      【讨论】:

      • 感谢您的回复,我会发布我的解决方案。