【问题标题】:Java SSL handshake error - Tomcat keystoreJava SSL 握手错误 - Tomcat 密钥库
【发布时间】:2016-02-13 18:28:24
【问题描述】:

我尝试通过 SSL 连接(在它们之间发送一些数据)我的独立应用和 Tomcat 提供的其他应用:

https://tomcat_server:8843/app

很遗憾,我的独立应用程序中出现错误:

原因:javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径 在 com.sun.net.ssl.internal.ssl.Alerts.getSSLException(未知来源) 在 com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(未知来源) 在 com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(未知来源) 在 com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(未知来源) 在 com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(未知来源) 在 com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(未知来源) 在 com.sun.net.ssl.internal.ssl.Handshaker.processLoop(未知来源) 在 com.sun.net.ssl.internal.ssl.Handshaker.process_record(未知来源) 在 com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(未知来源) 在 com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(未知来源) 在 com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(未知来源) 在 com.sun.net.ssl.internal.ssl.AppOutputStream.write(未知来源) 在 java.io.BufferedOutputStream.flushBuffer(未知来源) 在 java.io.BufferedOutputStream.flush(未知来源) 在 org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(HttpConnection.java:827) 在 org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.flushRequestOutputStream(MultiThreadedHttpConnectionManager.java:1525) 在 org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:1975) 在 org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:993) 在 org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:397) 在 org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:170) 在 org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:396) 在 org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:324) 在 org.apache.commons.vfs.provider.http.HttpClientFactory.createConnection(HttpClientFactory.java:101) ... 9 更多

如果我将 url 定义为 http 它可以正常工作:

http://tomcat_server:8080/app

我认为这也不是应用程序的问题。我在另一台 Tomcat 服务器上使用相同的应用程序尝试了同样的事情,它通过 https 工作。这些服务器之间的唯一区别是我没有在该服务器上创建有效的密钥库文件(pfx)。我当然不能使用相同的密钥库,因为它的域不同(我也通过浏览器访问这个应用程序)。 服务器上的 Tomcat 日志中没有任何内容。也许我在创建密钥库时做错了什么。

以下是我使用 openssl 工具和我的密钥、证书和中间证书生成密钥库文件的方式:

openssl pkcs12 -export -out certificate.pfx -inkey server.key -in server.crt -certfile intermediate.crt

这是我的连接器配置:

protocol="org.apache.coyote.http11.Http11Protocol"
       port="8443" maxThreads="200"
       scheme="https" secure="true" SSLEnabled="true"
       keystoreFile="/path/to/keystore/certificate.pfx" keystorePass="changeit"  ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA"
       keystoreType="PKCS12" clientAuth="false" sslProtocol="TLS"/>

两台服务器都有相同的配置,所以我认为它必须是证书。有人知道怎么解决吗?

【问题讨论】:

  • 也许你需要应用端的证书文件。
  • @disable1992 正如我所写,同一个应用程序适用于第二个 Tomcat(不同的密钥库)。

标签: java tomcat ssl


【解决方案1】:

您需要在 JDK 安全中导入证书。按照以下 2 步操作即可完成。

  • Step-1 转到java安全目录下

/path/to/java/jdk/jre/lib/security

  • Step-2 运行以下命令

keytool -import -keystore cacerts -file /path/to/your/cert.cer

【讨论】:

    【解决方案2】:

    您的应用程序必须使用您添加到为 8443 指定的密钥库的证书的公共部分的信任库。这可以通过使用系统属性来完成:

    -Djavax.net.ssl.trustStore=/path/to/truststore/truststore.jks
    -Djavax.net.ssl.trustStorePassword=truststorepassword
    

    【讨论】:

      【解决方案3】:

      运行: openssl s_client -connect [working_server]:[working_port] 然后对不工作的服务器执行相同的操作。比较结果;根据您的描述,它们之间可能没有通用证书。 “损坏”服务器的证书链中的一个证书必须在您应用的信任库中才能正常工作(日志表明它们不是);最好使用根证书,但在某些业务案例中,您可能更喜欢中间证书或叶证书本身。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-09-16
        • 1970-01-01
        • 2017-02-11
        • 2016-11-19
        • 1970-01-01
        • 2015-02-03
        • 2016-08-08
        • 2016-04-13
        相关资源
        最近更新 更多