当前位置: 首页 > 知识库问答 >
问题:

太阳安全验证器。ValidatorException:SunCertPathBuilderException-导入证书时

酆耀
2023-03-14

我越来越不正常了

太阳安全验证器。ValidatorException:PKIX路径生成失败:sun。安全供应商。certpath。SunCertPathBuilderException:找不到请求目标的有效证书路径

我已在该位置设置SSL证书

C:\Program Files\AdoptOpenJDK\jdk-11.0.9.11-hotspot\lib\security

keytool -import -keystore cacerts -file C:\Users\test\Desktop\Certificate\oCertificate.cer

但我在点击服务器时遇到了上述异常。

结果我看到我已经将证书添加到Jdk cacerts文件中,但它工作了两天,然后又出现了同样的错误。我无法让它工作,我能够成功ping服务器,但它再次显示异常。

共有3个答案

史谦
2023-03-14

正如其他答案所指出的,根据您使用的HTTP客户端的不同,需要正确设置的内容列表很长,而且各不相同,但假设您遵循了其他答案中提供的信息,我将检查以下内容:

  1. 确保证书已正确导入cacerts文件。这可能会被软件更新、组策略(如果您在windows域上)、意外更改JVM等覆盖。仔细检查正在使用的JVM的路径

如果您已经检查了所有这些,但它仍然不起作用,那么您可能需要使用系统属性javax打开SSL日志记录。网使用$java-Djavax在Oracle JSSE站点上进行调试,如下所述。网debug=all将给出握手的所有信息。这将需要一些时间来解决,但答案将在那里。

郏博瀚
2023-03-14

您报告的错误表示您的应用程序无法与远程对等体建立受信任的SSL连接,因为它无法找到有效的认证路径。

这对我来说似乎很奇怪,这就是为什么它在几天前起作用,而现在却不起作用:可能是服务器更改了证书,或者是您的设置以某种方式发生了更改。

SSL配置在很大程度上取决于用于连接远程服务器的软件:如果使用标准Java类,如URLConnectionHttpURLConnection,或Apache HttpClient或OkHttp等库,SSL配置可能会有所不同。区别主要与该软件是否使用Java安全套接字扩展(JSSE)有关。

假设您正在使用JSSE,为了成功配置您的信任关系,您需要正确配置一个TrustManager,更具体地说,一个X509TrustManager。从文档:

TrustManager的主要职责是确定是否应该信任所提供的身份验证凭据。

基本上,您可以通过两种方式配置这个X509TrustManager

另一方面,您可以创建自己的实现。例如:

// This KeyStore contains the different certificates for your server
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(
  new FileInputStream("/path/to/serverpublic.keystore"),
  "yourserverpublickeystorepassword".toCharArray()
);

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); // SunX509
tmf.init(keyStore);
TrustManager[] trustManagers = tmf.getTrustManagers();

SSLContext sslContext = SSLContext.getInstance("TLS");
// You can configure your client for mutual authentication 
// and/or provide a SecureRanhtml" target="_blank">dom also if you wish
sslContext.init(null, trustManagers, null); 

请考虑阅读这个问题作为一个完整的例子。

或者,另一方面,正如您正在做的那样,您可以正确配置标准的TrustManagerFactory

如上述留档所示,标准的TrustManagerFactory使用以下过程尝试按照指定的顺序查找信任材料:

  1. 首先,可以使用javax。网ssl。trustStoresystem属性,指向运行应用程序时包含受信任服务器证书的密钥石。如果javax。网ssl。还定义了trustStorePassword系统属性,然后使用其值在打开truststore之前检查truststore中数据的完整性
  • 如果文件java home/lib/security/jssecacerts存在,则使用该文件
  • 如果文件java home/lib/security/cacerts存在,则使用该文件
  • 如果这两个文件都不存在,那么SSL密码套件是匿名的,不执行任何身份验证,因此不需要信任库

无论使用哪种选择的机制,您都必须确保密钥库包含信任远程服务器所需的所有证书,不仅包括SSL证书,还包括证书链中的所有证书。

openssl提供了一个有用的命令,允许您获取SSL连接中使用的所有证书:

openssl s_client -showcerts -connect google.com:443

当然,可以根据需要修改域。

它将输出不同的证书;确保保存每个证书,包括-–开始证书--–结束证书-,并将它们包含在密钥库中。

这个方便的实用程序可能也有助于实现这一目的:正如项目自述文件中指出的那样,它基本上会尝试连接到远程对等机,并保存必要的证书信息。这篇相关文章提供了有关该工具的更多信息。

容鸿畴
2023-03-14

您描述的问题是运行keytool导入证书会导致此错误吗?请提供选项-trustcacerts,并查看相关文档:

导入新的受信任证书

在将证书添加到密钥库之前,keytool命令会使用密钥库中已有的受信任证书,尝试构建从该证书到自签名证书(属于根CA)的信任链,以验证该证书。

如果指定了-trustcacerts选项,则会为信任链考虑其他证书,即名为cacerts的文件中的证书。

如果keytool命令无法建立从要导入的证书到自签名证书(来自密钥库或cacerts文件)的信任路径,则会打印证书信息,并提示用户通过将显示的证书指纹与从其他(受信任的)信息源(可能是证书所有者)获取的指纹进行比较来验证。在将证书作为受信任的证书导入之前,请务必确保该证书有效。然后,用户可以选择停止导入操作。如果指定了-noprompt选项,则不会与用户进行交互。

资料来源:https://docs.oracle.com/en/java/javase/11/tools/keytool.html

或者,您可能会发现keytool对用户不太友好,您可能会喜欢其他软件,如:https://keystore-explorer.org/downloads.html更多

或者,如果问题是您的(TLS客户端,甚至是TLS服务器)软件出现了一些证书问题,可能是因为jccampanero已经建议服务器可能已切换到不同的证书,或者据我所知,服务器可能实际上是负载平衡器后面的多个不同服务器,它们可能并不都具有相同的证书。(或者您安装了一些Java更新来替换默认的cacerts文件?)

在问题的情况下,我强烈建议阅读JSSE-留档和启用调试日志与java选项-Djavax.net.debug=all或可能比all少一点,如握手请参阅Java11文档在:

https://docs.oracle.com/en/java/javase/11/security/java-secure-socket-extension-jsse-reference-guide.html#GUID-31B7E142-B874-46E9-8DD0-4E18EC0EB2CF

这显示了应用程序使用的确切TrustStore、服务器在握手过程中提供的证书以及作为TLS握手一部分的许多其他协商内容。

如果您希望完全控制您信任的颁发证书的人,您可以配置自己的信任库,而不是可以在Java安装之外使用以下选项的默认信任库:

java -Djavax.net.ssl.trustStore=samplecacerts \
     -Djavax.net.ssl.trustStorePassword=changeit \
     Application

我相信,研究这个调试日志应该可以直接解决这个问题,如果没有,请向我们提供一些相关的日志。

 类似资料:
  • 我的应用程序调用一个web服务,以便对该web服务中的特定用户进行身份验证。该web服务有自己的自签名CA证书。我正在使用该服务的POST REST调用,通过传递用户的用户名和密码来验证用户,但随后我收到了这个错误。。 我创建了一个密钥库,并将该服务器证书导入其中。我在应用程序中使用该密钥库来信任web服务。将证书导入JDK的cacerts可以解决我的问题,但该应用程序可以根据客户机的要求迁移到其

  • 我有一个类,它用一个xml点击一个安全的URL(以https开头),然后在最后处理xml并返回响应。但在这样做的同时,我也遇到了一些例外<代码>javax。网ssl。例外:太阳。安全验证器。ValidatorException:PKIX路径生成失败:sun。安全供应商。certpath。SunCertPathBuilderException:找不到请求目标的有效认证路径 我在谷歌上搜索了很多,找到

  • 我有三个基于java的web应用程序app1,app2和app3在生产。所有3个都由经过验证的CA进行验证,并托管在3个不同的Web服务器和http上。 下面是证书的层次结构,当我通过web浏览器点击这些应用程序时,我可以看到。 app1、app2证书租用人制度相同。E app3证书雇佣关系为 现在,当app1连接到app2时,一切正常。但当app1连接到app3时,会出现以下异常 现在我看了一下

  • 正在尝试从创建wsdl客户端https://example.com?wsdl.使用以下命令wsimport-keephttps://example.com?wsdl 我已经使用这个命令keytool-import-alias ctp-file C:\Users\ravi\Desktop\ctplive安装了ssl证书。cer-keystore C:\Program Files\Java\jdk1。

  • 我有一个EV证书为我的网站的多个子域。允许的域列表包括: 我希望使用一个具有自定义CNAME为和EV ssl证书的Cloudfront CDN。但是每当我试图在AWS证书管理器中导入它时,我都会得到以下错误。 我的证书就像

  • 我会非常感谢任何能指引我正确方向的人。