tomcat - HTTPS 通信失败,jdk 1.6(32 位客户端)与 jdk 1.8(64 位)服务器 : READ: Unknown-3. 3 警报,长度 = 2

标签 tomcat ssl https httpclient sslhandshakeexception

这是我对stackoverflow的第一个问题。我正在尝试两个 tomcat 之间的 HTTPS 通信:

  1. 客户端 Tomcat,使用 JDK1.6 32 位。
  2. 服务器 Tomcat,使用 JDK1.8 64 位。

HTTPs 请求的客户端代码:

HttpClient hc = new HttpClient();
hc.startSession(monitAppURL);
int code = hc.executeMethod(poster);

我得到的异常:

Received fatal alert: handshake_failure

我通过使用 -Djavax.net.debug=ssl:handshake:verbose 启动 JVM 获得了更详细的异常:

trigger seeding of SecureRandom
done seeding SecureRandom
Allow unsafe renegotiation: true
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: true
Monitoring service @dealy::nap 30::30, setSoTimeout(0) called
Monitoring service @dealy::nap 30::30, setSoTimeout(0) called
%% No cached client session
*** ClientHello, TLSv1 RandomCookie: GMT: 1468994533 bytes = { 100, 134, 165, 203, 220, 40, 175, 72, 89, 189, 99, 104, 208, 177, 19, 59, 234, 210, 59, 1, 57, 254, 73, 155, 253, 82, 102, 221 } Session ID: {}
Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WIT _AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CB _SHA, SSL_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_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_S A, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_W TH_DES40_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]

Compression Methods: { 0 }

*** Monitoring service @dealy::nap 30::30, WRITE: TLSv1 Handshake, length = 75
Monitoring service @dealy::nap 30::30, WRITE: SSLv2 client hello message, length = 101
Monitoring service @dealy::nap 30::30, READ: Unknown-3.3 Alert, length = 2
Monitoring service @dealy::nap 30::30, RECV TLSv1 ALERT: fatal, Handshake_failure
Monitoring service @dealy::nap 30::30, called closeSocket() Monitoring service
@dealy::nap 30::30, handling exception: javax.net.ssl.SSLHan shakeException: Received fatal alert: handshake_failure

我已经使用 set JAVA_OPTS="-Dhttps.protocols="TLSv1"-Djdk.tls.client.protocols="TLSv1"-Dcom.sun.net.ssl.checkRevocation=false -Ddeployment 启动了我的 JVM .security.TLSv1=true -Djavax.net.debug=ssl:handshake:verbose -Dsun.security.ssl.allowUnsafeRenegotiation=true -Djdk.tls.enableRC4CipherSuites=true -Ddeployment.security.TLSv1=true -Dhttps.cipherSuites=TLS_ECDHE_RSA_WITH_AES _128_CBC_SHA

但仍然无法摆脱错误。我已经花了很多时间。请帮我解决这个问题。

最佳答案

我找到了解决问题的方法, 1.发生了什么事? Java 6 默认使用 SSlv2Client Hello 消息进行握手,即使它使用的是 TLSv1 协议(protocol)。握手消息格式为 sslv2Client hello

@dealy::nap 30::30, WRITE: SSLv2 client hello message,length=101

我的服务器使用的是 java 8,出于安全原因禁用了 SSLv3,

jdk.tls.disabledAlgorithms=SSLv3

这导致我的握手消息失败,因为我的客户端正在发送 sslv2Client 问候消息,即使选择了 TLSv1 协议(protocol)进行通信。它被报告为错误:

https://serverfault.com/questions/637880/disabling-sslv3-but-still-supporting-sslv2hello-in-apache

如果您在 jvm 中禁用 Sslv3,它也会禁用 sslv2Client Hello 消息支持

2.我做了什么? apache httpClient默认总是采用jvm原有的协议(protocol)栈进行通信。这就是为什么我的 jvm 参数不适用于 httpclient。

因此,我通过添加以下代码覆盖了 httpclient SSL 通信。

SSLContext sslContext = SSLContexts.custom()
  .useTLS()
  .build();

SSLConnectionSocketFactory f = new SSLConnectionSocketFactory(
  sslContext,
  new String[]{"TLSv1"},   
  null,
  SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

HttpClient hc = HttpClients.custom()
  .setSSLSocketFactory(f)
  .build();

最后,Apache httpclient 启动了TLSv1 格式的握手消息进行通信。

我希望这能帮助面临同样问题的人,

谢谢。

关于tomcat - HTTPS 通信失败,jdk 1.6(32 位客户端)与 jdk 1.8(64 位)服务器 : READ: Unknown-3. 3 警报,长度 = 2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41936661/

相关文章:

java - 如何在Tomcat中更改应用程序部署路径

java - 如何配置子域以用于 Java Servlet?

java - 未检测到 Tomcat JDBC 连接器

域上的 SSL 连接错误

java - 加载小程序时的 Tomcat 安全警告

python - SSL 错误 "unexpected message"

forms - CakePHP HTTPS 安全支付表单

http -//和http ://之间的区别

https - 将 CHttpFile 与 HTTPS 站点一起使用

tomcat - 在 Tomcat v7.0 服务器中发布失败