我们使用Oracle jdk 1.7.0_71和Tomcat 7.0.55。不幸的是,我们开始在服务器之间的SSL连接期间收到以下异常:
javax.net.ssl.SSLHandshakeException: server certificate change is restrictedduring renegotiation
这是什么意思?怎么预防呢?
Tomcat重新启动后,该异常消失了。
全栈:
Caused by: javax.net.ssl.SSLHandshakeException: server certificate change is restrictedduring renegotiation at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) ~[?:1.7.0_71] at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1884) ~[?:1.7.0_71] at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276) ~[?:1.7.0_71] at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:266) ~[?:1.7.0_71] at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1402) ~[?:1.7.0_71] at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:209) ~[?:1.7.0_71] at sun.security.ssl.Handshaker.processLoop(Handshaker.java:878) ~[?:1.7.0_71] at sun.security.ssl.Handshaker.process_record(Handshaker.java:814) ~[?:1.7.0_71] at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016) ~[?:1.7.0_71] at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312) ~[?:1.7.0_71] at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:702) ~[?:1.7.0_71] at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122) ~[?:1.7.0_71] at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) ~[?:1.7.0_71] at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140) ~[?:1.7.0_71] at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:506) ~[commons-httpclient-3.1.jar:?] at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114) ~[commons-httpclient-3.1.jar:?] at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096) ~[commons-httpclient-3.1.jar:?] at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398) ~[commons-httpclient-3.1.jar:?] at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171) ~[commons-httpclient-3.1.jar:?] at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397) ~[commons-httpclient-3.1.jar:?] at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323) ~[commons-httpclient-3.1.jar:?] at org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor.executePostMethod(CommonsHttpInvokerRequestExecutor.java:205) ~[spring-web-3.2.9.RELEASE.jar:3.2.9.RELEASE] at org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor.doExecuteRequest(CommonsHttpInvokerRequestExecutor.java:140) ~[spring-web-3.2.9.RELEASE.jar:3.2.9.RELEASE] at org.springframework.remoting.httpinvoker.AbstractHttpInvokerRequestExecutor.executeRequest(AbstractHttpInvokerRequestExecutor.java:136) ~[spring-web-3.2.9.RELEASE.jar:3.2.9.RELEASE] at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.executeRequest(HttpInvokerClientInterceptor.java:192) ~[spring-web-3.2.9.RELEASE.jar:3.2.9.RELEASE] at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.executeRequest(HttpInvokerClientInterceptor.java:174) ~[spring-web-3.2.9.RELEASE.jar:3.2.9.RELEASE] at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.invoke(HttpInvokerClientInterceptor.java:142) ~[spring-web-3.2.9.RELEASE.jar:3.2.9.RELEASE] ... 160 more
客户端层代码中的此错误消息是由于在最近的Java更新中遵循“ SSL V3.0 Poodle漏洞- CVE-2014-3566”而进行代码强化的结果。这是一个错误-如果您无法立即更新JRE,可以采用以下解决方法:
第一种选择 是在建立HTTPS连接时强制使用TLS协议:
如果可以将HttpClient更新到比4.3.6更新的版本,则默认情况下将禁用SSLv3,并且您的代码不应再报告此类异常。
对于从Java 7运行时进行的其他http访问,必须设置以下系统属性
-Dhttps.protocols="TLSv1"
第二种选择 是放宽客户端检查,以仍然允许具有以下属性的重新协商:
-Djdk.tls.allowUnsafeServerCertChange=true -Dsun.security.ssl.allowUnsafeRenegotiation=true
第三种选择 是根据Burp论坛中的这篇文章 “改进”服务器证书,以将群集成员的所有IP地址都包括为使用者替代名称。
第四个选项 是在添加此证书/重新协商检查之前,在7u41之前(要确认)降级Java版本。