【问题标题】:Configure an SSL connector for Tomcat, invoked by eclipse为 Tomcat 配置 SSL 连接器,由 eclipse 调用
【发布时间】:2017-05-24 07:47:54
【问题描述】:

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

应用程序运行,但其中一个 Web 服务调用失败,并显示有关“握手错误”的消息。我已经阅读了有关配置 SSL 连接器以供 Tomcat 使用的不同内容,但我还没有得到它的工作。

我立即感到困惑的是用于证书文件和证书密钥文件的密码。我目前有以下连接器:

    <Connector 
        SSLCertificateFile="c:\Program Files\Java\jdk1.7.0_07\jre\lib\security\csi_keystore.jks" 
        SSLCertificateKeyFile="c:\Program Files\Java\jdk1.7.0_07\jre\lib\security\jssecacerts" 
        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 Files\Java\jdk1.7.0_07\jre\lib\security\csi_keystore.jks" 
-Djavax.net.ssl.keyStorePassword=psw2 
-Djavax.net.ssl.trustStore="C:\Program Files\Java\jdk1.7.0_07\jre\lib\security\jssecacerts" 
-Djavax.net.ssl.trustStorePassword="psw2" 

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

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

=== 编辑 ===

好的,我现在明白了 JSSE 和 APR 是 Tomcat 使用的 SSL 通信的不同实现,并且每个配置都不同。我相当肯定我们正在使用 JSSE; Netbeans 配置是

-Djavax.net.ssl.keyStore="C:\Program Files\Java\jdk1.7.0_07\jre\lib\security\csi_keystore.jks" 
-Djavax.net.ssl.keyStorePassword=thePassword
-Djavax.net.ssl.trustStore="C:\Program Files\Java\jdk1.7.0_07\jre\lib\security\jssecacerts" 
-Djavax.net.ssl.trustStorePassword="thePassword" 

添加到命令行以执行服务器(以及其他参数),这对我来说就像 JSSE 参数。所以我将以下连接器放入 server.xml:

<Connector 
    SSLEnabled="true"
    clientAuth="false" 
    keystoreFile="c:\Program Files\Java\jdk1.7.0_07\jre\lib\security\csi_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)

当然还有更多……

【问题讨论】:

  • 您使用的是哪种证书?自签名证书还是 CA 生成的证书?
  • 它是来自我们调用的站点 web 服务站点的 CA 证书。
  • 您是否在密钥库中安装了 CA 根证书和您的证书? (为了“锚定”您的证书的信任链,您必须在密钥库中导入 CA 根证书)
  • 是的 - 这在 Netbeans 下有效,我只是想用 eclipse 让它工作。
  • 我有一些工作,请参阅下面@AbelRoussi 的答案中的 cmets。

标签: java eclipse tomcat ssl


【解决方案1】:

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

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

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

这是来自Tomcat Apache web site 的 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" />

仅供参考:使用 APR SSLCertificateFileSSLCertificateKey 属性用于代替keystoreFile 中使用的属性 JSSE 实施。

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

【讨论】:

  • 那么,keystoreFile 和 keystorePass 用于 JSSE,而 SSLCertificateFile 和 SSLCertificateKeyFile 和 SSLPassword 用于 APR?
  • APR 中,SSLCertificateFileSSLCertificateKey 属性用于代替 JSSE 实现中使用的 keystoreFile 属性
  • 还是不行。如果您正在关注并希望提供帮助,请参阅上述问题中的编辑...
  • 好吧,我有一些东西在起作用:我将在 Tomcat 命令行上为 Netbeans 提供的参数放入 Eclipse 的 Window / Preferences / Java / Installed JREs / Default VM arguments 中。现在确实失败的 ewb 服务调用成功了,我可以继续其他调试。但是很高兴知道如何使用 server.xml 来完成此操作,如果有人对此有建议,我仍然很感兴趣。
猜你喜欢
  • 2020-09-04
  • 1970-01-01
  • 1970-01-01
  • 2021-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-05
  • 1970-01-01
相关资源
最近更新 更多