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

这是最初的问题。

我得到这个错误:

详细消息sun.security.validator.ValidatorException: PKIX路径 构建失败: provider.certpath. suncertpathbuilderexception:不能 找到请求目标的有效认证路径 导致javax.net.ssl.SSLHandshakeException: validatorexception: PKIX路径构建 失败:sun.security.provider.certpath.SunCertPathBuilderException: 无法找到请求目标的有效认证路径

我使用Tomcat 6作为web服务器。我在同一台机器上的不同端口的不同Tomcats上安装了两个HTTPS web应用程序。假设App1(端口8443)和App2(端口443)。App1连接到App2。当App1连接到App2时,我得到上述错误。我知道这是一个非常常见的错误,所以在不同的论坛和网站上找到了许多解决方案。我在两个Tomcats的server.xml中有以下条目:

keystoreFile="c:/.keystore" 
keystorePass="changeit"

每个站点都说明了app2给出的证书不在app1 jvm的可信存储区中的相同原因。这似乎也是真的,当我试图在IE浏览器中点击相同的URL,它工作(与升温,有一个问题与此网站的安全证书。在这里我说继续这个网站)。但是当相同的URL被Java客户端(在我的情况下)击中时,我得到上述错误。为了把它放到信任库中,我尝试了以下三个选项:

选项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

结果

但是什么都不管用。

最后工作是执行Java方法建议如何处理无效的SSL证书与Apache HttpClient?通过Pascal Thivent,即执行程序InstallCert。

但这种方法适用于开发盒设置,但我不能在生产环境中使用它。

我想知道为什么上面提到的三种方法都不工作,而我已经通过设置在App2服务器的server.xml中提到了相同的值,在truststore中也提到了相同的值

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());

当前回答

如果您使用的是JDK 11,则该文件夹中不再包含JRE。certs的位置是jdk-11.0.11/lib/security/cacerts。

其他回答

您需要将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的信息可以在这里找到。

我的观点是: 在我的例子中,cacerts不是一个文件夹,而是一个文件,而且它在两个路径上呈现 发现后,错误消失后复制。jks文件到该文件。

# locate cacerts    
/usr/java/jdk1.8.0_221-amd64/jre/lib/security/cacerts
/usr/java/jre1.8.0_221-amd64/lib/security/cacerts

备份后,我复制。jks。

cp /path_of_jks_file/file.jks /usr/java/jdk1.8.0_221-amd64/jre/lib/security/cacerts
cp /path_of_jks_file/file.jks /usr/java/jre1.8.0_221-amd64/lib/security/cacerts

注意:这个基本技巧解决了Genexus项目中的这个错误,尽管文件。jks也在Tomcat的server.xml文件中。

这里似乎是记录臭名昭著的PKIX错误消息的另一个可能原因的好地方。在花了太长时间查看密钥库和信任库内容以及各种java安装配置之后,我意识到我的问题在于……一个错字。

输入错误意味着我还使用密钥存储库作为信任存储库。由于我的公司根CA没有被定义为keystore中的独立证书,而只是证书链的一部分,并且没有在其他任何地方定义(即cacerts),我一直得到PKIX错误。

在一次失败的发布之后(这是prod配置,在其他地方是可以的),经过两天的挠头,我终于看到了错别字,现在一切都好了。

希望这能帮助到一些人。

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证书链(ie浏览器中有锁图标),单击锁即可查看证书。

•进入证书的“详细信息”和“复制到文件”。复制为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文件中。

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

对我来说,这个错误也出现在试图连接到一个NGINX反向代理背后的进程,它正在处理SSL。

事实证明,问题在于一个没有连接整个证书链的证书。 当我添加中间证书时,问题就解决了。

希望这能有所帮助。