编辑:我在我的博客上尝试以更加整洁的方式格式化了问题和已接受答案。
以下是原始问题。
我遇到了这个错误:
详细信息 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 作为 web 服务器。在同一台机器上,我安装了两个 HTTPS Web 应用程序,它们分别位于不同的 Tomcat 上,使用不同的端口。假设 App1 (端口 8443)连接到 App2 (端口 443)。当 App1 连接到 App2 时,我会收到上述错误。我知道这是一个非常常见的错误,因此在不同的论坛和站点上找到了许多解决方案。我在两个 Tomcats 的 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
结果
但是没有任何一种方法起作用。
最后起作用的方法是执行Pascal Thivent在如何处理Apache HttpClient中无效的SSL证书?中建议的Java方法,即执行InstallCert程序。
但是这种方法适用于开发环境设置,而我不能在生产环境中使用它。
我想知道为什么在App1中将相同的值在App2服务器的server.xml
中和信任存储中提到了三种上述方法都不起作用,同时在App1程序中通过以下方式设置:
System.setProperty("javax.net.ssl.trustStore", "C:/.keystore") and System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
有关更多信息,以下是我建立连接的方法:
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());