HTTPS通信失败,使用jdk 1.8(64位)服务器的jdk 1.6(32位客户端):READ:Unknown-3.3 Alert,length = 2

问题描述:

这是我的第一个问题*。我正在尝试两个tomcat之间的HTTPS通信:HTTPS通信失败,使用jdk 1.8(64位)服务器的jdk 1.6(32位客户端):READ:Unknown-3.3 Alert,length = 2

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

对于HTTPS客户端代码请求:

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

例外,我得到:

收到致命警报:handshake_failure

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

SecureRandom的

触发播种完成播种的SecureRandom
允许不安全的重新协商:真
允许旧的Hello报文:真
是初始握手:真
是安全的重新谈判:真
监控服务@dealy :: nap 30 :: 30,setSoTimeout(0)叫做
监控服务@dealy :: nap 30 :: 30,setSoTimeout(0)叫
%%没有缓存的客户端会话
*** ClientHello, TLSv1 RandomCookie:GMT:1468994533字节= {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} 会话ID:{}
密码套件:[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甲,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]

压缩方法:{0}

***监控服务@dealy :: nap 30 :: 30,WRITE:TLSv1握手,长度= 75
监控服务@dealy :: nap 30 :: 30,WRITE:SSLv2 client hello message,length = 101
监控服务@dealy ::小睡30 :: 30,READ:未知-3.3异动,长度= 2
监测服务@dealy ::小睡30 :: 30,RECV的TLSv1 ALERT:致命的,Handshake_failure
监视服务@ dealy :: nap 30 :: 30,调用closeSocket()监视服务
@dealy :: nap 30 :: 30,处理异常:javax.net.ssl.SSLHan shakeException:收到致命警报:handshake_failure

我开始我的JVM与set JAVA_OPTS="-Dhttps.protocols="TLSv1" -Djdk.tls.client.protocols="TLSv1" -Dcom.sun.net.ssl.checkRevocation=false -Ddeployment.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

但依然没能得到错误的旅程。我已经花了很多时间。请帮我解决这个问题。

+0

你可以升级客户端tomcat实例来使用JDK 1.7吗?我发现JDK1.6对TLS1有问题 –

+0

不,我不能升级jdk 1.6,因为它是一个传统的应用程序。该通信正在使用HTTP,但在HTTPS上失败 – sss121522

我找到了解决方案,我的问题, 1.发生了什么? Java 6中默认使用SSlv2Client Hello报文握手,即使它使用的TLSv1议定书(草案)握手消息格式sslv2Client你好

@dealy ::午睡30 :: 30,写协议:SSLv2客户端hello消息,长度= 101

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

jdk.tls.disabledAlgorithms = SSLv3的

这引起了我握手消息失败,因为我的客户发送sslv2Client hello消息,即使使用TLSv1协议是choosen的报告为错误通信。其:

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

如果您在JVM中禁用它的SSLv3也禁用sslv2Client你好消息支持

2.我做了什么? apache httpClient默认使用jvm原始协议栈进行通信。这就是为什么我的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格式的握手消息进行通信。

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

谢谢。

+0

请注意,'ALLOW_ALL_HOSTNAME_VERIFIER'会让您的代码信任所有证书,这是不推荐的。 –

+0

非常感谢您的支持! – sss121522