无法使用 java 7 中制作的应用程序访问 java 14 中制作的 web 服务
Posted
技术标签:
【中文标题】无法使用 java 7 中制作的应用程序访问 java 14 中制作的 web 服务【英文标题】:cannot access webservice made in java 14 using application made in java 7 【发布时间】:2021-04-07 13:30:50 【问题描述】:我的应用程序是在 java 7 中开发的,我必须访问在 java 14 中开发的“https”Web 服务。我收到“收到致命警报:handshake_failure”
这是堆栈跟踪
*** ClientHello, TLSv1.2
RandomCookie: GMT: 1592616408 bytes = 12, 135, 232, 24, 158, 109, 182, 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());
这是我服务器的虚拟机参数
在我的 jre7\lib\security 我已经更新了 local_policy.jar 和 US_export_policy.jar
我错过了什么。我是否需要添加密码套装,或者它可能是浏览器问题(我使用的是 firefox 84.0)或其他问题。我无法升级到 java8。
【问题讨论】:
【参考方案1】:根据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 浏览器与您的应用程序充当后端服务客户端的问题完全无关。只有当网络浏览器直接连接到后端服务器时,这才有意义。
【讨论】:
我无法切换到 java8,因为通过调用 Web 服务,我正在实时旧 Web 应用程序中添加一些功能。请您告诉如何使用本地代理从最近的 TLS1.2 密码执行“HTTPS 转换” @IlaVerma 您可以安装像 Mitmproxy 这样的本地代理。它进行 HTTPS 拦截,因此它自己与服务器握手。由于它使用 Python,它不受“Java 7 限制”的约束,因此可以提供不同的密码。 mitmproxy 只是一个示例,其他进行 HTTPS 拦截的代理也应该可以工作。重要的部分是代理至少支持您的 Java 7 列表支持的一种密码和使用的服务器中的一种。然后,在您的 Java 应用程序中,您必须配置对该服务器的每个请求以使用该本地代理。 感谢您提供解决方案。但我认为我的公司不会允许我在服务器中安装代理。使用编码或添加一些罐子,证书什么都不能做? @IlaVerma 我对你的老板有一个关于这个话题的明确声明:“如果你使用不受支持的长期死机软件,你必须面对后果。一切都是有代价的。” -谢谢我和我的老板讨论我们是否可以升级到 java 8以上是关于无法使用 java 7 中制作的应用程序访问 java 14 中制作的 web 服务的主要内容,如果未能解决你的问题,请参考以下文章