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