为eclipse调用的Tomcat配置SSL连接器



我有一个web应用程序,当通过Netbeans调用时,它在Tomcat下运行。我正试图让它在eclipse下运行。

应用程序运行,但其中一个web服务调用失败,并显示一条关于"握手错误"的消息。我读过关于配置Tomcat使用的SSL连接器的不同内容,但我还没有让它发挥作用。

我直接感到困惑的是用于证书文件和证书密钥文件的密码。我现在有以下连接器:

<Connector 
SSLCertificateFile="c:Program FilesJavajdk1.7.0_07jrelibsecuritycsi_keystore.jks" 
SSLCertificateKeyFile="c:Program FilesJavajdk1.7.0_07jrelibsecurityjssecacerts" 
SSLCipherSuite="RC4-SHA:HIGH:!ADH:!SSLv2:@STRENGTH" 
SSLEnabled="true" 
SSLPassword="psw1" 
SSLProtocol="all" acceptCount="100" disableUploadTimeout="true" 
enableLookups="false" executor="tomcatThreadPool" maxThreads="200" 
port="443" scheme="https" secure="true"/>

从Netbeans运行时传递给Tomcat的以下参数:

-Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=8888 -DproxySet=true 
-Xms1024m -Xmx1024m -server -Djava.awt.headless=true -XX:NewSize=256m 
-XX:MaxNewSize=256m -XX:PermSize=512m -XX:MaxPermSize=512m 
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC 
-Djavax.net.ssl.keyStore="C:Program FilesJavajdk1.7.0_07jrelibsecuritycsi_keystore.jks" 
-Djavax.net.ssl.keyStorePassword=psw2 
-Djavax.net.ssl.trustStore="C:Program FilesJavajdk1.7.0_07jrelibsecurityjssecacerts" 
-Djavax.net.ssl.trustStorePassword="psw2" 

查看Tomcat文档,在我的示例中没有看到"SSLCertificateFile"one_answers"SSLCertificateKeyFile"参数;这些准确吗?密码是什么?

文档中有一个示例,包括参数"keystore"one_answers"keypass";这些是等价的吗?还是首选?我还需要密钥文件及其密码吗?

===编辑===

好的,我现在了解到JSSE和APR是Tomcat使用的SSL通信的不同实现,并且每种通信的配置都是不同的。我确信我们正在使用JSSE;Netbeans配置是

-Djavax.net.ssl.keyStore="C:Program FilesJavajdk1.7.0_07jrelibsecuritycsi_keystore.jks" 
-Djavax.net.ssl.keyStorePassword=thePassword
-Djavax.net.ssl.trustStore="C:Program FilesJavajdk1.7.0_07jrelibsecurityjssecacerts" 
-Djavax.net.ssl.trustStorePassword="thePassword" 

添加到命令行以执行服务器(以及其他参数),这对我来说就像JSSE参数

<Connector 
SSLEnabled="true"
clientAuth="false" 
keystoreFile="c:Program FilesJavajdk1.7.0_07jrelibsecuritycsi_keystore.jks"
keystorePass="changeit" 
maxThreads="200" 
port="443" 
protocol="org.apache.coyote.http11.Http11NioProtocol" 
scheme="https" 
secure="true"
sslProtocol="TLS"
enableLookups="false" 
/>

但我在里面看不到任何关于"trustStore"或其密码的信息。这些参数也应该在server.xml中吗?或者你看到我做错了什么吗?

我已经打开了详细调试(-Djavax.net.debug=all);在我得到的异常点上有以下几行:

[write] MD5 and SHA1 hashes:  len = 16
0000: 14 00 00 0C C5 D8 0A 7E   A5 D1 18 87 5A D6 EE EB  ............Z...
Padded plaintext before ENCRYPTION:  len = 36
0000: 14 00 00 0C C5 D8 0A 7E   A5 D1 18 87 5A D6 EE EB  ............Z...
0010: 7D D4 BE 23 3C DB 78 99   10 43 94 45 10 09 20 8A  ...#<.x..C.E.. .
0020: C7 41 74 B0                                        .At.
main, WRITE: TLSv1 Handshake, length = 36
[Raw write]: length = 41
0000: 16 03 01 00 24 5A 3F 83   45 A2 AA 61 7E F6 11 2D  ....$Z?.E..a...-
0010: 43 9D 15 A7 46 D7 FC 6B   F5 F2 26 BB 3E 35 D5 ED  C...F..k..&.>5..
0020: 0D 3F 81 84 6B BF 12 69   48                       .?..k..iH
[Raw read]: length = 5
0000: 15 03 01 00 02                                     .....
[Raw read]: length = 2
0000: 02 28                                              .(
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1 ALERT:  fatal, handshake_failure
%% Invalidated:  [Session-4, SSL_RSA_WITH_RC4_128_SHA]
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
main, called close()
main, called closeInternal(true)
DEBUG:[22:01:36] Could not close WebServiceConnection
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1977)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1093)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1328)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1355)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:515)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1090)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)
at org.springframework.ws.transport.http.HttpUrlConnection.getRequestOutputStream(HttpUrlConnection.java:84)

当然,还有更多。。。

首先,您应该知道Tomcat可以使用两种不同的SSL实现:

  • 作为Java运行时的一部分提供的JSSE实现(自1.4起)
  • Apache Portable Runtime(APR)实现,或所谓的tomcat的"本地库",默认情况下使用OpenSSL引擎(这是最好的做法)

您现在使用的是第二个实现(我想您已经在服务器上安装了它),但是SSLCertificateFile应该是证书文件的路径,SSLCertificateKeyFile应该是密钥文件的路径。您应该添加另一个名为SSLCertificateChainFile的属性,该属性应该指向CA根证书的位置。

以下是Tomcat Apache网站的APR连接器配置示例

<Connector port="443" maxHttpHeaderSize="8192"
maxThreads="150"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
SSLEnabled="true"
SSLCertificateFile="path/to/certificateFile/conf/localhost.crt"
SSLCertificateKeyFile="path/to/privatekeyFile/localhost.key" 
SSLPassword="keyStorePassw"
SSLCertificateChainFile="path/to/CAroot/certificate" keyAlias="youKeyAlias" 
SSLVerifyClient="optional" SSLProtocol="TLSv1+TLSv1.1+TLSv1.2" /> 

否则如果您想使用JSSE实现,这里有一个如何使用的示例:

<Connector port="443" maxHttpHeaderSize="8192" maxThreads="150"
minSpareThreads="25" maxSpareThreads="75" enableLookups="false" 
disableUploadTimeout="true" acceptCount="100" scheme="https" 
secure="true" SSLEnabled="true" clientAuth="false" 
sslProtocol="TLS" keyAlias="yourKeyAlias"
keystoreFile="/path/to/yourKeystore/file.jks"
keystorePass="keyStorePassw" />

FYI:使用APRSSLCertificateFileSSLCertificateKey使用属性来代替中使用的keystoreFile属性JSSE实现。

有关使用SSL配置tomcat的更多信息,tomcat使用SSL

最新更新