编辑:我尝试在我的 博客中以更形象的方式格式化问题并接受答案。
这是原始问题。
我收到此错误:
详细消息 sun.security.validator.ValidatorException: PKIX 路径构建失败: sun.security.provider.certpath.SunCertPathBuilderException: 无法找到请求目标的有效证书路径 导致 javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径
详细消息 sun.security.validator.ValidatorException: PKIX 路径构建失败: sun.security.provider.certpath.SunCertPathBuilderException: 无法找到请求目标的有效证书路径
导致 javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径
我使用 Tomcat 6 作为网络服务器。我在不同端口上的不同 Tomcat 上安装了两个 HTTPS Web 应用程序,但在同一台机器上。说 App1(端口 8443)和 App2(端口 443)。App1 连接到 App2。当 App1 连接到 App2 时,出现上述错误。我知道这是一个非常常见的错误,因此在不同的论坛和网站上遇到了许多解决方案。server.xml我在两个 Tomcat中都有以下条目:
server.xml
keystoreFile="c:/.keystore" keystorePass="changeit"
每个站点都说app2提供的证书不在app1 jvm的受信任存储中的原因相同。当我试图在 IE 浏览器中点击相同的 URL 时,这似乎也是如此,它可以工作(随着变暖,这个网站的安全证书有问题。这里我说继续这个网站)。但是,当 Java 客户端(在我的情况下)点击相同的 URL 时,我得到了上述错误。因此,为了把它放在信任库中,我尝试了以下三个选项:
System.setProperty("javax.net.ssl.trustStore", "C:/.keystore"); System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
在环境变量中设置以下
CATALINA_OPTS -- param name -Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value
JAVA_OPTS -- param name -Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value
但没有任何效果。
最后的工作 是执行如何使用 Apache HttpClient 处理无效 SSL 证书中建议的 Java 方法?通过 Pascal Thivent 即执行程序 InstallCert。
但是这种方法适用于 devbox 设置,但我不能在生产环境中使用它。
我想知道为什么当我server.xml通过设置提到 App2 服务器中的相同值和信任库中的相同值时,上述三种方法不起作用
System.setProperty("javax.net.ssl.trustStore", "C:/.keystore") and System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
在 App1 程序中。
有关更多信息,这是我建立连接的方式:
URL url = new URL(urlStr); URLConnection conn = url.openConnection(); if (conn instanceof HttpsURLConnection) { HttpsURLConnection conn1 = (HttpsURLConnection) url.openConnection(); conn1.setHostnameVerifier(new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }); reply.load(conn1.getInputStream());
您需要将 App2的证书添加到所用 JVM 的信任库文件中,该文件位于$JAVA_HOME\lib\security\cacerts.
$JAVA_HOME\lib\security\cacerts
首先,您可以通过运行以下命令检查您的证书是否已经在信任库中:( keytool -list -keystore "$JAVA_HOME/jre/lib/security/cacerts"您不需要提供密码)
keytool -list -keystore "$JAVA_HOME/jre/lib/security/cacerts"
如果您的证书丢失,您可以使用浏览器下载它并使用以下命令将其添加到信任库中:
keytool -import -noprompt -trustcacerts -alias <AliasName> -file <certificate> -keystore <KeystoreFile> -storepass <Password>
例子:
keytool -import -noprompt -trustcacerts -alias myFancyAlias -file /path/to/my/cert/myCert.cer -keystore /path/to/my/jdk/jre/lib/security/cacerts/keystore.jks -storepass changeit
导入后,您可以再次运行第一个命令以检查您的证书是否已添加。
可以在此处找到 Sun/Oracle 信息。