解决 javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed 错误?

新手上路,请多包涵

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

这是原始问题。

我收到此错误:

详细消息 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 许可协议

阅读 2.6k
2 个回答

您需要将 App2 的证书添加到位于 $JAVA_HOME\lib\security\cacerts 的所用 JVM 的信任库文件中。

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

原文由 SimonSez 发布,翻译遵循 CC BY-SA 4.0 许可协议

javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径

• 当我遇到错误时,我尝试用谷歌搜索表达式的含义,我发现,当服务器更改其 HTTPS SSL 证书时会出现此问题,而我们的旧版本 java 无法识别根证书颁发机构 (CA) .

• 如果您可以在浏览器中访问 HTTPS URL,则可以更新 Java 以识别根 CA。

• 在您的浏览器中,转到Java 无法访问的HTTPS URL。点击HTTPS证书链(Internet Explorer中有锁图标),点击锁查看证书。

• 转到证书的“详细信息”和“复制到文件”。以 Base64 (.cer) 格式复制它。它将保存在您的桌面上。

• 安装证书时忽略所有警报。

• 这就是我收集试图访问的URL 的证书信息的方式。

现在我必须让我的 java 版本知道证书,这样它就不会拒绝识别 URL。在这方面我必须提到,我用谷歌搜索发现根证书信息默认保留在 JDK 的 \jre\lib\security 位置,默认访问密码是: changeit。

要查看 cacerts 信息,请遵循以下过程:

• 单击开始按钮–>运行

• 键入cmd。命令提示符打开(您可能需要以管理员身份打开它)。

• 转到您的 Java/jreX/bin 目录

• 输入以下内容

keytool -list -keystore D:\Java\jdk1.5.0_12\jre\lib\security\cacerts

它给出了密钥库中包含的当前证书的列表。它看起来像这样:

 C:\Documents and Settings\NeelanjanaG>keytool -list -keystore D:\Java\jdk1.5.0_12\jre\lib\security\cacerts

Enter keystore password:  changeit

Keystore type: jks

Keystore provider: SUN

Your keystore contains 44 entries

verisignclass3g2ca, Mar 26, 2004, trustedCertEntry,

Certificate fingerprint (MD5): A2:33:9B:4C:74:78:73:D4:6C:E7:C1:F3:8D:CB:5C:E9

entrustclientca, Jan 9, 2003, trustedCertEntry,

Certificate fingerprint (MD5): 0C:41:2F:13:5B:A0:54:F5:96:66:2D:7E:CD:0E:03:F4

thawtepersonalbasicca, Feb 13, 1999, trustedCertEntry,

Certificate fingerprint (MD5): E6:0B:D2:C9:CA:2D:88:DB:1A:71:0E:4B:78:EB:02:41

addtrustclass1ca, May 1, 2006, trustedCertEntry,

Certificate fingerprint (MD5): 1E:42:95:02:33:92:6B:B9:5F:C0:7F:DA:D6:B2:4B:FC

verisignclass2g3ca, Mar 26, 2004, trustedCertEntry,

Certificate fingerprint (MD5): F8:BE:C4:63:22:C9:A8:46:74:8B:B8:1D:1E:4A:2B:F6

• 现在我必须将之前安装的证书包含到cacerts 中。

• 为此,程序如下:

 keytool -import -noprompt -trustcacerts -alias ALIASNAME -file FILENAME_OF_THE_INSTALLED_CERTIFICATE -keystore PATH_TO_CACERTS_FILE -storepass PASSWORD

如果您使用的是 Java 7:

 keytool -importcert -trustcacerts -alias ALIASNAME -file PATH_TO_FILENAME_OF_THE_INSTALLED_CERTIFICATE -keystore PATH_TO_CACERTS_FILE -storepass changeit

• 然后它将证书信息添加到cacert 文件中。

这是我为上述异常找到的解决方案!

原文由 NDeveloper 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题