无法使用在 java 7 中创建的应用程序访问在 java 14 中创建的 web 服务

问题描述

我的应用程序是用 java 7 开发的,我必须访问一个用 java 14 开发的“https”网络服务。我收到“收到致命警报:handshake_failure”

这是堆栈跟踪

*** ClientHello,TLSv1.2
RandomCookie:  GMT: 1592616408 bytes = { 12,135,232,24,158,109,182,90,77,217,233,239,161,116,121,128,150,234,201,224,14,34,171,199,213,212,98 }
Session ID:  {}
Cipher Suites: [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_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 signature_algorithms,signature_algorithms: SHA512withECDSA,SHA512withRSA,SHA384withECDSA,SHA384withRSA,SHA256withECDSA,SHA256withRSA,SHA224withECDSA,SHA224withRSA,SHA1withECDSA,SHA1withRSA,SHA1withDSA,MD5withRSA
Extension server_name,server_name: [host_name: collabdds.gov.in]
***
http-localhost%2F127.0.0.1-8080-7,WRITE: TLSv1.2 Handshake,length = 246
http-localhost%2F127.0.0.1-8080-7,READ: TLSv1.2 Alert,length = 2
http-localhost%2F127.0.0.1-8080-7,RECV TLSv1 ALERT:  fatal,handshake_failure
http-localhost%2F127.0.0.1-8080-7,called closeSocket()
http-localhost%2F127.0.0.1-8080-7,handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
http-localhost%2F127.0.0.1-8080-7,called close()
http-localhost%2F127.0.0.1-8080-7,called closeInternal(true)
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)

我的代码


private static SSLSocketFactory getSSLSocketFactory() {
    try 
    {
        final TrustManager[] trustAllCerts = new TrustManager[] {
        new x509trustmanager() {
        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates,String s) throws CertificateException {      }
        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates,String s) throws CertificateException {      }
        @Override
        public X509Certificate[] getAcceptedissuers() {
        return new X509Certificate[0];
        }
        }
        };
        final SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
        sslContext.init(null,null,new SecureRandom());
        SSLContext.setDefault(sslContext);
        return sslContext.getSocketFactory();
} catch (Exception e) {
e.printstacktrace();
}
return null;
}

我在另一个函数中的某处写了以下

((HttpsURLConnection)conn).setSSLSocketFactory(getSSLSocketFactory());

这是我服务器的 VM 参数

this is my server's VM arguments

在我的 jre7\lib\security 我有更新 local_policy.jar 和 US_export_policy.jar

我错过了什么。我需要添加密码套装还是可能是浏览器问题(我使用的是 Firefox 84.0)或其他问题。我无法升级到 java8。

解决方法

根据SSLLabs,服务器collabdds.gov.in仅支持四种TLS1.2密码(服务器也支持TLS1.3,但Java 7根本不支持):

TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256

您的 Java 版本不支持任何这些密码,因此无法建立连接并且 TLS 握手失败。

Java 7 在在线和 Web 服务方面是一匹死马。如果你想访问这个服务器,我强烈建议你切换到 Java 8。或者你必须使用一个本地代理来执行从最近的 TLS1.2 密码到你旧的和不安全的 Java 版本的“HTTPS 转换”。

在我看来,您应该真正考虑升级到 Java 8。无论如何,您早晚都必须这样做。

请注意,所使用的 Web 浏览器与您的应用程序充当后端服务客户端的问题完全无关。仅当 Web 浏览器直接连接到后端服务器时,这才有意义。