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

时间:2017-01-30 13:05:16

标签: tomcat ssl https httpclient sslhandshakeexception

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

  1. 客户端Tomcat,使用32位JDK1.6。
  2. 服务器Tomcat,使用64位JDK1.8。
  3. HTTPs请求的客户端代码:

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

    我得到例外:

      

    收到致命警报:handshake_failure

    通过使用-Djavax.net.debug=ssl:handshake:verbose

    启动JVM,我获得了更详细的异常
      

    触发SecureRandom的播种
      完成播种SecureRandom
      允许不安全的重新谈判:真实   允许遗留问候消息:真实   初始握手:真实   是安全的重新谈判:真实的   监控服务@dealy :: nap 30 :: 30,setSoTimeout(0)称为
      监控服务@dealy :: nap 30 :: 30,setSoTimeout(0)称为
      %%没有缓存的客户端会话
       *** 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}   会议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 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]

         

    压缩方法:{0}

         

    ***监控服务@dealy :: nap 30 :: 30,WRITE:TLSv1握手,长度= 75
      监控服务@dealy :: nap 30 :: 30,WRITE:SSLv2客户端问候消息,长度= 101
      监控服务@dealy :: nap 30 :: 30,READ:Unknown-3.3 Alert,length = 2
      监控服务@dealy :: nap 30 :: 30,RECV TLSv1 ALERT:致命,Handshake_failure
      监控服务@dealy :: nap 30 :: 30,名为closeSocket()监控服务
      @dealy :: nap 30 :: 30,处理异常:javax.net.ssl.SSLHan shakeException:收到致命警报:handshake_failure

    我已经使用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

    启动了我的JVM

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

1 个答案:

答案 0 :(得分:0)

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

  

@dealy :: nap 30 :: 30,WRITE:SSLv2客户端问候消息,长度= 101

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

  

jdk.tls.disabledAlgorithms = SSLv3的

这导致我的握手消息失败,因为我的客户端正在发送sslv2Client hello消息,即使选择了TLSv1协议进行通信。它报告为bug:

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

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

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格式握手消息进行通信。

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

谢谢。

相关问题