SSLHandshakeException:在tomcat 7服务器上设置密码时收到致命警报:handshake_failure [英] SSLHandshakeException: Received fatal alert: handshake_failure when setting ciphers on tomcat 7 server
问题描述
我有一个Tomcat7网络服务器,我试图通过将此连接器添加到 server.xml
文件中来配置为接受安全连接:
< Connector SSLEnabled =true
acceptCount =100
connectionTimeout =20000
executor =
keyAlias =server
keystoreFile =c:\opt\engine\conf\tc.keystore
keystorePass =o39UI12z
maxKeepAliveRequests = 15
port =8443
protocol =HTTP / 1.1
redirectPort =8443
scheme =https
secure =true
sslProtocol =TLS/>
我使用的是使用此命令生成的自签名证书:
%JAVA_HOME%/ bin / keytool -genkeypair -keystore c:\opt\engine\conf\tc.keystore -storepass o39UI12z-keypass o39UI12z -dnamecn = Company,ou = Company,o = Com,c = US-alias server -validity 36500
客户端我有一个spring应用程序使用 RestTemplate
与服务器连接。在应用程序上下文启动时,我以这种方式启动 restTemplate
实例:
final ClientHttpRequestFactory clientHttpRequestFactory =
new MyCustomClientHttpRequestFactory(new NullHostNameVerifier(),serverInfo);
restTemplate.setRequestFactory(clientHttpRequestFactory);
MyCustomClientHttpRequestFactory类如下所示:
public class MyCustomClientHttpRequestFactory扩展SimpleClientHttpRequestFactory {
private static final Logger LOGGER = LoggerFactory
.getLogger(MyCustomClientHttpRequestFactory.class);
private final HostnameVerifier hostNameVerifier;
private final ServerInfo serverInfo;
public MyCustomClientHttpRequestFactory(final hostnameVerifier hostNameVerifier,
final ServerInfo serverInfo){
this.hostNameVerifier = hostNameVerifier;
this.serverInfo = serverInfo;
@Override
protected void prepareConnection(final HttpURLConnection connection,final String httpMethod)
throws IOException {
if(连接实例HttpsURLConnection){
((HttpsURLConnection)连接).setHostnameVerifier(hostNameVerifier);
((HttpsURLConnection)连接).setSSLSocketFactory(initSSLContext()
.getSocketFactory());
}
super.prepareConnection(connection,httpMethod);
}
私人SSLContext initSSLContext(){
try {
System.setProperty(https.protocols,TLSv1);
//设置ssl信任管理器。验证我们的服务器指纹
final SSLContext ctx = SSLContext.getInstance(TLSv1);
final SslThumbprintVerifier verifier = new SslThumbprintVerifier(serverInfo);
final ThumbprintTrustManager thumbPrintTrustManager =
new ThumbprintTrustManager(null,verifier);
ctx.init(null,new TrustManager [] {thumbPrintTrustManager},null);
return ctx;
} catch(final Exception ex){
LOGGER.error(
尝试初始化HTTP安全管理器时抛出异常,ex);
返回null;
}
}
直到这里一切正常。 / strong>当我在SslThumbprintVerifier类中放置一个断点时,代码到达了这一点,并且还到了NullHostNameVerifier类。现在我想通过限制密码套件来扩展安全性,我把这个属性添加到我开头提供的连接器中:
密码=TLS_KRB5_WITH_RC4_128_SHA,SSL_RSA_WITH_RC4_128_SHA,SSL_DHE_RSA_WITH_AES_256_CBC_SHA,SSL_RSA_WITH_AES_256_CBC_SHA,SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,SSL_RSA_WITH_3DES_EDE_CBC_SHA,SSL_DHE_RSA_WITH_AES_128_CBC_SHA,SSL_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_RC4_128_SHA,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_KRB5_WITH_3DES_EDE_CBC_SHA
现在,当我运行客户端代码时,我得到这个异常:
javax.net.ssl.SSLHandshakeException:收到的致命警报:handshake_failure
/ pre>
这发生在
restTemplate.doExecu te()
方法。代码不会像添加密码那样到达指纹验证器类和主机名验证器类。
在调试中我检查了
ctx.getSocketFactory()。getSupportedCipherSuites()
显示:[SSL_RSA_WITH_RC4_128_MD5,SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_256_CBC_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_SHA,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_WITH_DES40_CBC_SHA,TLS_EMPTY_RENEGOTIATION_INFO_SCSV,SSL_RSA_WITH_NULL_MD5,SSL_RSA_WITH_NULL_SHA,SSL_DH_anon_WITH_RC4_128_MD5,TLS_DH_anon_WITH_AES_128_CBC_SHA ,TLS_DH_anon_WITH_AES_256_CBC_SHA,SSL_DH_anon_WITH_3DES_EDE_CBC_SHA,SSL_DH_anon_WITH_DES_CBC_SHA,SSL_DH_anon_EXPORT_WITH_RC4_40_MD5,SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA,TLS_KRB5_WITH_RC4_128_SHA,TLS_KRB5_WITH_RC4_128_MD5,TLS_KRB5_WITH_3DES_EDE_CBC_SHA,TLS_KRB5_WITH_3DES_EDE_CBC_MD5,TLS_KRB5_WITH_DES_CBC_SHA,TLS_KRB5_WITH_DES_CBC_MD5,TLS_KRB5_EXPORT_WITH_RC4_40_SHA,TLS_KRB5_EXPORT_WITH_RC4_40_MD5,TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA,TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5]
,并检查
ctx.getSocketFactory()。getDefaultCipherSuites()
:[SSL_RSA_WITH_RC4_128_MD5,SSL_RSA_WITH_RC4_128_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_256_CBC_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_S HA,SSL_DHE_RSA_WITH_DES_CBC_SHA,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_WITH_DES40_CBC_SHA,TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
和最后的
ctx.getSupportedSSLParameters()。getCipherSuites()
:[SSL_RSA_WITH_RC4_128_MD5,SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_256_CBC_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_SHA,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_WITH_DES40_CBC_SHA,TLS_EMPTY_RENEGOTIATION_INFO_SCSV, SSL_RSA_WITH_NULL_MD5,SSL_RSA_WITH_NULL_SHA,SSL_DH_anon_WITH_RC4_128_MD5,TLS_DH_anon_WITH_AES_128_CBC_SHA,TLS_DH_anon_WITH_AES_256_CBC_SHA,SSL_DH_anon_WITH_3DES_EDE_CBC_SHA,SSL_DH_anon_WITH_DES_CBC_SHA,SSL_DH_anon_EXPORT_WITH_RC4_40_MD5,SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA,TLS_KRB5_WITH_RC4_128_SHA,TLS_KRB5_WITH_RC4_128_MD5,TLS_KRB5_WITH_3DES_EDE_CBC_SHA,TLS_KRB5_WITH_3DES_EDE_CBC_MD5,TLS_KRB5_WITH_DES_CBC_SHA,TLS_KRB5_WITH_DES_CBC_MD5,TLS_KRB5_EXPORT_WITH_RC4_40_SHA,TLS_KRB5_EXPORT_WITH_RC4_40_MD5,TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA,TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5]
据我所知,如果客户端支持/启用的密码套件与服务器支持的密码套件之间有交集,那么它应该有效(我们有这样的交集
SSL_RSA_WITH_RC4_128_SHA
)。但是我收到这个错误。
在下一步中,我添加了这个java参数:
-Djavax.net.debug = ssl,握手,失败
日志只显示客户端 - 你好,没有服务器端口响应:
[2013- 03-20 15:29:51.315] [INFO] data-service-pool-37 SecureRandom的System.out触发种子
[2013-03-20 15:29:51.315] [INFO] data-service-pool -37 System.out完成种子SecureRandom
[2013-03-20 15:30:38.894] [INFO] data-service-pool-37 System.out允许不安全的重新协商:false
[2013-03 -20 15:30:38.894] [INFO] data-service-pool-37 System.out允许传统的hello消息:true
[2013-03-20 15:30:38.8 94] [INFO] data-service-pool-37 System.out初始握手:true
[2013-03-20 15:30:38.894] [INFO] data-service-pool-37 System.out安全重新协商:false
[2013-03-20 15:30:38.894] [INFO] data-service-pool-37 System.out %%没有缓存的客户端会话
[2013-03-20 15 :30:38.894] [INFO] data-service-pool-37 System.out *** ClientHello,TLSv1
[2013-03-20 15:30:38.941] [INFO] data-service-pool-37 System.out RandomCookie:GMT:1363720446 bytes = {99,249,173,214,110,82,58,52,189,92,74,169,133,128,250,109,160,64,112,253 ,50,160,255,196,85,93,33,172}
[2013-03-20 15:30:38.941] [INFO] data-service-pool-37 System.out会话ID:{}
[信息] data-service-pool-37 System.out密码套件:[SSL_RSA_WITH_RC4_128_MD5,SSL_RSA_WITH_RC4_128_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA ,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_256_CBC_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_SHA,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_WITH_DES40_CBC_SHA,TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
[二零一三年三月二十日15:30:38.956] [INFO] DATA- service-pool-37 System.out压缩M方法:{0}
[2013-03-20 15:30:38.956] [INFO] data-service-pool-37 System.out ***
[2013-03-20 15:30 :38.956] [INFO] data-service-pool-37 System.out data-service-pool-37,WRITE:TLSv1握手,长度= 81
[2013-03-20 15:30:38.956] [INFO ] data-service-pool-37 System.out data-service-pool-37,READ:TLSv1 Alert,length = 2
[2013-03-20 15:30:38.956] [INFO] data-service- pool-37 System.out data-service-pool-37,RECV TLSv1 ALERT:fatal,handshake_failure
[2013-03-20 15:30:38.972] [INFO] data-service-pool-37 System.out data-service-pool-37,称为closeSocket()
[2013-03-20 15:30:38.972] [INFO] data-service-pool-37 System.out data-service-pool-37,处理异常:javax.net.ssl.SSLHandshakeException:接收到的致命警报:handshake_failure
从server.xml中删除密码时,它再次工作。
另外我会提到我正在同一台机器上测试服务器和客户端。我尝试将客户端请求中的服务器的ip设置为localhost和实际的机器ip并且在两种情况下都不起作用。此外,我将这台服务器运行在不同的linux机器上(密钥库是在linux机器上生成的,当然还有一个linux路径),而且它仍然可以运行,没有密码,并且停止使用密码。解决方案嗯,我解决了这个问题。看来,通过创建自签名证书,使用keytool,不提供-keyalg参数使密钥对算法默认为DSA。我的密码套件都不包括DSA算法。在这种情况下,虽然客户端和服务器在密码套件之间都有交集,但两者都不适用于密钥算法。
添加
-keyalg RSA
生成密钥库时,解决了这个问题。I have a Tomcat7 web-server which I tried to configure to accept secure connections by adding this connector to the
server.xml
file:<Connector SSLEnabled="true" acceptCount="100" connectionTimeout="20000" executor="tomcatThreadPool" keyAlias="server" keystoreFile="c:\opt\engine\conf\tc.keystore" keystorePass="o39UI12z" maxKeepAliveRequests="15" port="8443" protocol="HTTP/1.1" redirectPort="8443" scheme="https" secure="true" sslProtocol="TLS"/>
I'm using a self-signed certificate generated using this command:
%JAVA_HOME%/bin/keytool -genkeypair -keystore c:\opt\engine\conf\tc.keystore -storepass o39UI12z-keypass o39UI12z-dname "cn=Company, ou=Company, o=Com, c=US" -alias server -validity 36500
On the client side I have a spring application that connects with the server using
RestTemplate
. On application context startup I initalize therestTemplate
instance this way:final ClientHttpRequestFactory clientHttpRequestFactory = new MyCustomClientHttpRequestFactory(new NullHostNameVerifier(), serverInfo); restTemplate.setRequestFactory(clientHttpRequestFactory);
The class MyCustomClientHttpRequestFactory looks like this:
public class MyCustomClientHttpRequestFactory extends SimpleClientHttpRequestFactory { private static final Logger LOGGER = LoggerFactory .getLogger(MyCustomClientHttpRequestFactory.class); private final HostnameVerifier hostNameVerifier; private final ServerInfo serverInfo; public MyCustomClientHttpRequestFactory (final HostnameVerifier hostNameVerifier, final ServerInfo serverInfo) { this.hostNameVerifier = hostNameVerifier; this.serverInfo = serverInfo; } @Override protected void prepareConnection(final HttpURLConnection connection, final String httpMethod) throws IOException { if (connection instanceof HttpsURLConnection) { ((HttpsURLConnection) connection).setHostnameVerifier(hostNameVerifier); ((HttpsURLConnection) connection).setSSLSocketFactory(initSSLContext() .getSocketFactory()); } super.prepareConnection(connection, httpMethod); } private SSLContext initSSLContext() { try { System.setProperty("https.protocols", "TLSv1"); // Set ssl trust manager. Verify against our server thumbprint final SSLContext ctx = SSLContext.getInstance("TLSv1"); final SslThumbprintVerifier verifier = new SslThumbprintVerifier(serverInfo); final ThumbprintTrustManager thumbPrintTrustManager = new ThumbprintTrustManager(null, verifier); ctx.init(null, new TrustManager[] { thumbPrintTrustManager }, null); return ctx; } catch (final Exception ex) { LOGGER.error( "An exception was thrown while trying to initialize HTTP security manager.", ex); return null; } }
Up until here everything worked fine. When I put a break point in the SslThumbprintVerifier class, the code reached to this point and also to the NullHostNameVerifier class. This was tested in production and worked great.
Now I wanted to extend security by limiting the cipher suites and I added this property to the Connector I presented at the beginning:
ciphers="TLS_KRB5_WITH_RC4_128_SHA,SSL_RSA_WITH_RC4_128_SHA,SSL_DHE_RSA_WITH_AES_256_CBC_SHA,SSL_RSA_WITH_AES_256_CBC_SHA,SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,SSL_RSA_WITH_3DES_EDE_CBC_SHA,SSL_DHE_RSA_WITH_AES_128_CBC_SHA,SSL_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_RC4_128_SHA,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_KRB5_WITH_3DES_EDE_CBC_SHA"
Now when I'm running the client code I get this exception:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
This happens in the
restTemplate.doExecute()
method. The code doesn't reach to the thumbprint verifier class nor to the host name verifier class as it did before adding the ciphers.In debug I checked the
ctx.getSocketFactory().getSupportedCipherSuites()
which showed:[SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_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_SHA, 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_WITH_DES40_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV, SSL_RSA_WITH_NULL_MD5, SSL_RSA_WITH_NULL_SHA, SSL_DH_anon_WITH_RC4_128_MD5, TLS_DH_anon_WITH_AES_128_CBC_SHA, TLS_DH_anon_WITH_AES_256_CBC_SHA, SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, SSL_DH_anon_WITH_DES_CBC_SHA, SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, TLS_KRB5_WITH_RC4_128_SHA, TLS_KRB5_WITH_RC4_128_MD5, TLS_KRB5_WITH_3DES_EDE_CBC_SHA, TLS_KRB5_WITH_3DES_EDE_CBC_MD5, TLS_KRB5_WITH_DES_CBC_SHA, TLS_KRB5_WITH_DES_CBC_MD5, TLS_KRB5_EXPORT_WITH_RC4_40_SHA, TLS_KRB5_EXPORT_WITH_RC4_40_MD5, TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA, TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5]
and also checked
ctx.getSocketFactory().getDefaultCipherSuites()
:[SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_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_SHA, 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_WITH_DES40_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
and lastly the
ctx.getSupportedSSLParameters().getCipherSuites()
:[SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_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_SHA, 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_WITH_DES40_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV, SSL_RSA_WITH_NULL_MD5, SSL_RSA_WITH_NULL_SHA, SSL_DH_anon_WITH_RC4_128_MD5, TLS_DH_anon_WITH_AES_128_CBC_SHA, TLS_DH_anon_WITH_AES_256_CBC_SHA, SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, SSL_DH_anon_WITH_DES_CBC_SHA, SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, TLS_KRB5_WITH_RC4_128_SHA, TLS_KRB5_WITH_RC4_128_MD5, TLS_KRB5_WITH_3DES_EDE_CBC_SHA, TLS_KRB5_WITH_3DES_EDE_CBC_MD5, TLS_KRB5_WITH_DES_CBC_SHA, TLS_KRB5_WITH_DES_CBC_MD5, TLS_KRB5_EXPORT_WITH_RC4_40_SHA, TLS_KRB5_EXPORT_WITH_RC4_40_MD5, TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA, TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5]
As far as I understand, if there's an intersection between the client's supported/enabled cipher suites and the server's supported cipher suites it should work (we have such intersection with
SSL_RSA_WITH_RC4_128_SHA
for example). And yet I'm getting this error.In the next step I added this java parameter:
-Djavax.net.debug=ssl,handshake,failure
The log showed only the client-hello, with no server-hello response:
[2013-03-20 15:29:51.315] [INFO ] data-service-pool-37 System.out trigger seeding of SecureRandom [2013-03-20 15:29:51.315] [INFO ] data-service-pool-37 System.out done seeding SecureRandom [2013-03-20 15:30:38.894] [INFO ] data-service-pool-37 System.out Allow unsafe renegotiation: false [2013-03-20 15:30:38.894] [INFO ] data-service-pool-37 System.out Allow legacy hello messages: true [2013-03-20 15:30:38.894] [INFO ] data-service-pool-37 System.out Is initial handshake: true [2013-03-20 15:30:38.894] [INFO ] data-service-pool-37 System.out Is secure renegotiation: false [2013-03-20 15:30:38.894] [INFO ] data-service-pool-37 System.out %% No cached client session [2013-03-20 15:30:38.894] [INFO ] data-service-pool-37 System.out *** ClientHello, TLSv1 [2013-03-20 15:30:38.941] [INFO ] data-service-pool-37 System.out RandomCookie: GMT: 1363720446 bytes = { 99, 249, 173, 214, 110, 82, 58, 52, 189, 92, 74, 169, 133, 128, 250, 109, 160, 64, 112, 253, 50, 160, 255, 196, 85, 93, 33, 172 } [2013-03-20 15:30:38.941] [INFO ] data-service-pool-37 System.out Session ID: {} [2013-03-20 15:30:38.941] [INFO ] data-service-pool-37 System.out Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_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_SHA, 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_WITH_DES40_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV] [2013-03-20 15:30:38.956] [INFO ] data-service-pool-37 System.out Compression Methods: { 0 } [2013-03-20 15:30:38.956] [INFO ] data-service-pool-37 System.out *** [2013-03-20 15:30:38.956] [INFO ] data-service-pool-37 System.out data-service-pool-37, WRITE: TLSv1 Handshake, length = 81 [2013-03-20 15:30:38.956] [INFO ] data-service-pool-37 System.out data-service-pool-37, READ: TLSv1 Alert, length = 2 [2013-03-20 15:30:38.956] [INFO ] data-service-pool-37 System.out data-service-pool-37, RECV TLSv1 ALERT: fatal, handshake_failure [2013-03-20 15:30:38.972] [INFO ] data-service-pool-37 System.out data-service-pool-37, called closeSocket() [2013-03-20 15:30:38.972] [INFO ] data-service-pool-37 System.out data-service-pool-37, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
When removing the ciphers from the server.xml it works again. Also I will mention that I'm testing both the server and the client on the same machine. I tried setting the server's ip in the client request to 'localhost' and to the actual machine ip and it didn't work in both cases. Also, I had this server running on a different linux machine (the keystore was generated on the linux machine with a linux path of course) and still - it works without the ciphers and stops working with the ciphers.
解决方案Well, I got this issue solved. It appears that by creating a self-signed certificate, using keytool, without providing -keyalg parameter makes the key-pair algorithm default to DSA. None of my ciphers suite included DSA algorithm. In that case, although the client and the server had intersection between their cipher-suites, neither was suitable for the key algoritm.
Adding
-keyalg RSA
when generating the keystore, solved the problem.这篇关于SSLHandshakeException:在tomcat 7服务器上设置密码时收到致命警报:handshake_failure的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!