这是我的第一个stackoverflow问题。我正在尝试两个tomcats之间的HTTPS通信:
HTTPs请求的客户端代码:
HttpClient hc = new HttpClient();
hc.startSession(monitAppURL);
int code = hc.executeMethod(poster);
我得到例外:
收到致命警报:handshake_failure
通过使用-Djavax.net.debug=ssl:handshake:verbose
:
触发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
但仍然无法摆脱错误。我已经花了很多时间。请帮我解决这个问题。
答案 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格式握手消息进行通信。
我希望这能帮助面临同样问题的人,
谢谢。