java - 解决 javax.net.ssl.SSLHandshakeException : sun. security.validator.ValidatorException : PKIX path building failed Error?

标签 java ssl https

编辑: 我试图在我的 blog 中以更形象的方式格式化问题和接受的答案。 .

这是原始问题。

我收到这个错误:

detailed message sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

cause javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

我使用 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") 和 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 .

首先,您可以通过运行以下命令检查您的证书是否已在信任库中: 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 信息here .

关于java - 解决 javax.net.ssl.SSLHandshakeException : sun. security.validator.ValidatorException : PKIX path building failed Error?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42126193/

相关文章:

java - 为什么使用 ActionListener 会破坏我的 Swing Applet?

java - DB2 BIGINT id 生成器

Java:如何使用一个 mouseListener 中的对象到另一个类?

wordpress - 站点报告(由某些浏览器) "not secure"尽管证书尚未过期

c# - sslStream.AuthenticateAsServer 忽略 RemoteCertificateValidationCallback

node.js - HTTPS 证书 - 如何在我的架构上设置

java - 如何为多个模块生成javadoc

java - 如何在 Java SSL 客户端应用程序中支持多个信任库

java - 如何从代号为 ConnectionRequest 的 http 和不安全的 https 站点获取响应? Android 10 中的 http 和 https 问题(在 Google Pixel 中)

node.js - 在 Node 和 Nginx 中终止 SSL/TLS 的位置