编辑: 我试图在我的 博客 上以更形象的方式格式化问题和接受的答案。
这是原始问题。
我收到此错误:
详细消息 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 时,出现上述错误。我知道这是一个非常常见的错误,因此在不同的论坛和网站上遇到了许多解决方案。我在两个 Tomcat 的 server.xml
中都有以下条目:
keystoreFile="c:/.keystore"
keystorePass="changeit"
每个站点都说 app2 提供的证书不在 app1 jvm 的受信任存储中的相同原因。当我尝试在 IE 浏览器中访问相同的 URL 时,这似乎也是正确的(随着变暖,该网站的安全证书存在问题。在这里我说继续访问该网站)。但是当 Java 客户端(在我的例子中)访问相同的 URL 时,我得到了上面的错误。所以为了把它放在信任库中,我尝试了这三个选项:
选项1
System.setProperty("javax.net.ssl.trustStore", "C:/.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
选项 2
在环境变量中设置如下
CATALINA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value
选项 3
在环境变量中设置如下
JAVA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value
结果
但没有任何效果。
最后起作用 的是执行 How to handle invalid SSL certificates with Apache HttpClient? 中建议的 Java 方法。由 Pascal Thivent 即执行程序 InstallCert。
但是这种方法适用于 devbox 设置,但我不能在生产环境中使用它。
我想知道为什么当我通过设置在 App2 服务器的 server.xml
中提到相同的值并且在信任库中提到相同的值时,上面提到的三种方法不起作用
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());
原文由 M Sach 发布,翻译遵循 CC BY-SA 4.0 许可协议
您需要将 App2 的证书添加到位于
$JAVA_HOME\lib\security\cacerts
的所用 JVM 的信任库文件中。首先,您可以通过运行以下命令检查您的证书是否已在信任库中:
keytool -list -keystore "$JAVA_HOME/jre/lib/security/cacerts"
(您无需提供密码)如果您的证书丢失,您可以通过使用浏览器下载并使用以下命令将其添加到信任库中来获取它:
例子:
导入后,您可以再次运行第一个命令来检查您的证书是否已添加。
可以在 此处 找到 Sun/Oracle 信息。