Java 收到致命警报:即使在禁用SSL后握手仍失败

Java 收到致命警报:即使在禁用SSL后握手仍失败,java,amazon-web-services,ssl,Java,Amazon Web Services,Ssl,我正在尝试使用Java的HttpsURLConnection(Java版本“1.8.091”)访问AWS API网关端点 但我收到“收到致命警报:握手失败”,即使我已禁用SSL证书验证 在下面的代码中,如果我对HttpsURLConnection.setDefaultHostnameVerifier(hv)进行注释,则一切正常。但我不允许在我的项目中对此发表评论,因为这会影响其他模块。我不确定为什么设置DefaultHostnameVerifier会导致握手失败 这是我的密码 public c

我正在尝试使用Java的HttpsURLConnection(Java版本“1.8.091”)访问AWS API网关端点

但我收到“收到致命警报:握手失败”,即使我已禁用SSL证书验证

在下面的代码中,如果我对HttpsURLConnection.setDefaultHostnameVerifier(hv)进行注释,则一切正常。但我不允许在我的项目中对此发表评论,因为这会影响其他模块。我不确定为什么设置DefaultHostnameVerifier会导致握手失败

这是我的密码

public class ShortTestCls {

      public static void disableCertificateValidation() {
            // 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 checkClientTrusted(X509Certificate[] certs, String authType) {}
                public void checkServerTrusted(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
            try {
              SSLContext sc = SSLContext.getInstance("SSL");

              sc.init(null, trustAllCerts, new SecureRandom());
              HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
              HttpsURLConnection.setDefaultHostnameVerifier(hv);
            } catch (Exception e) {}
          }


       public static void main(String... args) throws Exception{

            disableCertificateValidation();

             URL url = new URL("https://at0yve8x72.execute-api.us-west-2.amazonaws.com/test/v1/shorten?longurl=http://test.com");
             HttpURLConnection conn = (HttpURLConnection)url.openConnection(); 
             System.out.println("ResponseCoede ="+conn.getResponseCode());
       }
}
下面是SSL调试日志

trigger seeding of SecureRandom
done seeding SecureRandom
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
main, setSoTimeout(0) called
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 for TLSv1.1
%% No cached client session
*** ClientHello, TLSv1.2
RandomCookie:  GMT: 1455464809 bytes = { 69, 105, 27, 228, 90, 70, 203, 33, 93, 150, 199, 96, 215, 23, 7, 29, 152, 74, 251, 210, 120, 250, 42, 86, 39, 219, 146, 71 }
Session ID:  {}
Cipher Suites: [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_128_GCM_SHA256, 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
***
main, WRITE: TLSv1.2 Handshake, length = 193
main, READ: TLSv1.2 Alert, length = 2
main, RECV TLSv1.2 ALERT:  fatal, handshake_failure
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Exception in thread "main" javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at sun.security.ssl.Alerts.getSSLException(Unknown Source)
    at sun.security.ssl.Alerts.getSSLException(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.recvAlert(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at java.net.HttpURLConnection.getResponseCode(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
    at ShortTestCls.main(ShortTestCls.java:49)
从上面的日志来看,AWS API网关似乎完全拒绝了我的clienthello。我不知道我的代码出了什么问题

如果有任何建议能帮助我解决这个问题,我将不胜感激。有一些与javax.net.ssl.SSLHandshakeException有关的问题:但在那里找不到任何解决方案。

根据网站要求的扩展。根据调试输出,客户端不会发送此扩展

这可能与使用
setDefaultHostnameVerifier
时JDK1.8未能使用SNI的错误有关。因此,我建议删除此验证器并保留默认验证器。有关此问题的更多信息,请参阅

但我收到“收到致命警报:握手失败”,即使我已禁用SSL证书验证

握手失败与服务器证书的验证无关。因此,禁用验证将无济于事。除了禁用验证是一个坏主意,因为它削弱了SSL提供的保护点,中间人攻击是微不足道的。这个网站甚至没有必要。禁用主机名验证也很糟糕,而且此站点也不需要。

根据站点要求的扩展名。根据调试输出,客户端不会发送此扩展

这可能与使用
setDefaultHostnameVerifier
时JDK1.8未能使用SNI的错误有关。因此,我建议删除此验证器并保留默认验证器。有关此问题的更多信息,请参阅

但我收到“收到致命警报:握手失败”,即使我已禁用SSL证书验证


握手失败与服务器证书的验证无关。因此,禁用验证将无济于事。除了禁用验证是一个坏主意,因为它削弱了SSL提供的保护点,中间人攻击是微不足道的。这个网站甚至没有必要。禁用主机名验证也同样不好,此站点也不需要。

握手错误与服务器证书的验证无关,因此有助于不禁用验证(无论如何,这是一个坏主意)。握手错误与服务器证书的验证无关,因此有助于不禁用验证(无论如何,这是个坏主意)。谢谢您的帮助。对于生产,我将启用认证验证,但对于开发,我想禁用它。正如您提到的,我将继续使用默认验证器。@user3820681使用自定义SSLFactory facade查看答案神奇地允许自定义hostnameverifier。我在JDK7和JDK8中测试了相同的代码。这两种代码都可以工作,JDK8在没有faca的情况下失败反工厂。感谢您的帮助。对于生产,我将启用认证验证,但对于开发,我想禁用它。正如您所提到的,我将继续使用默认验证器。@user3820681使用自定义SSLFFactory facade查看答案神奇地允许自定义hostnameverifier。我在JDK7和JDK8中测试了相同的代码。这两种代码都可以工作,JDK8在从一个正面工厂出来。