Java 应用程序中的 PKIX 路径构建失败

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18378869/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 01:01:53  来源:igfitidea点击:

PKIX path building failed in Java application

javaexceptionsslcertificate

提问by JavaCake

I have been struggling for almost one week to get my applications up running after moving my applications from Windows 2000 to Windows 2008 R2 Server.

在将我的应用程序从 Windows 2000 移动到 Windows 2008 R2 Server 之后,我一直在努力让我的应用程序运行近一个星期。

The procedure:

步骤:

  1. Installed Java JDK 1.7.0_25
  2. Set system environment variable JAVA_HOMEto C:\Progra~1\Java\jdk1.7.0_25\
  3. Imported the certificate into cacerts with keytool
  4. Ensured that the certificate exists in keytoolwith -list.
  1. 已安装 Java JDK 1.7.0_25
  2. 将系统环境变量设置JAVA_HOMEC:\Progra~1\Java\jdk1.7.0_25\
  3. 将证书导入到 cacerts 中 keytool
  4. 确保在存在该证书keytool-list

I have tried to repeat step 3with InstallCertto ensure that i havent messed anything up.

我曾试图重复步骤3InstallCert,以确保我还没有把事情搞得一团糟。

The above methods did not solve my problem, so i tried to do it programmatically:

上述方法没有解决我的问题,所以我尝试以编程方式进行:

System.setProperty("javax.net.ssl.trustStore",
"C:/Progra~1/Java/jdk1.7.0_25/jre/lib/security/cacerts");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

Still without any luck. I am stuck and not quite sure which direction to go from here.

仍然没有任何运气。我被卡住了,不太确定从这里往哪个方向。

Stack trace:

堆栈跟踪:

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
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1886)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:515)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
    at util.SMS.send(SMS.java:93)
    at domain.ActivationSMSSenderMain.sendActivationMessagesToCustomers(ActivationSMSSenderMain.java:80)
    at domain.ActivationSMSSenderMain.<init>(ActivationSMSSenderMain.java:44)
    at domain.ActivationSMSSenderMain.main(ActivationSMSSenderMain.java:341)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
    at sun.security.validator.Validator.validate(Validator.java:260)
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1323)
    ... 14 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
    ... 20 more

UPDATE:

更新:

Both System.out.println(System.getProperty("javax.net.ssl.trustStore"));and System.out.println(System.getProperty("javax.net.ssl.keyStore"));

双方 System.out.println(System.getProperty("javax.net.ssl.trustStore"));System.out.println(System.getProperty("javax.net.ssl.keyStore"));

returns null.

返回null

采纳答案by jb1

I ran into similar issues whose cause and solution turned out both to be rather simple:

我遇到了类似的问题,其原因和解决方案都非常简单:

Main Cause: Did not import the proper cert using keytool

主要原因:没有使用 keytool 导入正确的证书

NOTE: Only import root CA (or your own self-signed) certificates

注意:仅导入根 CA(或您自己的自签名)证书

NOTE: don't import an intermediate, non certificate chain root cert

注意:不要导入中间的、非证书链根证书

Solution Example for imap.gmail.com

imap.gmail.com 的解决方案示例

  1. Determine the root CA cert:

    openssl s_client -showcerts -connect imap.gmail.com:993
    

    in this case we find the root CA is Equifax Secure Certificate Authority

  2. Download root CA cert.
  3. Verify downloaded cert has proper SHA-1 and/or MD5 fingerprints by comparing with info found here
  4. Import cert for javax.net.ssl.trustStore:

    keytool -import -alias gmail_imap -file Equifax_Secure_Certificate_Authority.pem
    
  5. Run your java code
  1. 确定根 CA 证书:

    openssl s_client -showcerts -connect imap.gmail.com:993
    

    在这种情况下,我们发现根 CA 是Equifax Secure Certificate Authority

  2. 下载根 CA 证书
  3. 通过与此处找到的信息进行比较,验证下载的证书是否具有正确的 SHA-1 和/或 MD5 指纹
  4. 导入证书javax.net.ssl.trustStore

    keytool -import -alias gmail_imap -file Equifax_Secure_Certificate_Authority.pem
    
  5. 运行你的java代码

回答by Sean Baker

Per your pastebin, you need to add the proxy.tkk.comcertificate to the truststore.

根据您的 pastebin,您需要将proxy.tkk.com证书添加到信任库。

回答by user207421

You've imported the certificate into the truststore of the JRE provided in the JDK, but you are running the java.exe of the JRE installed directly.

您已将证书导入到 JDK 中提供的 JRE 的信任库中,但您正在运行直接安装的 JRE 的 java.exe。

EDIT

编辑

For clarity, and to resolve the morass of misunderstanding in the commentary below, you need to import the certificate into the cacertsfile of the JRE you are intending to use,and that will rarely if ever be the one shipping inside the JDK, because clients won't normally have a JDK. Anything in the commentary below that suggests otherwise should be ignored as not expressing my intention here.

为了清楚起见,并解决下面评论中的误解,您需要将证书导入到您打算使用的 JREcacerts文件中,并且很少会在 JDK 内部传送证书,因为客户赢了通常没有 JDK。以下评论中任何暗示其他内容的内容都应该被忽略,因为这里没有表达我的意图。

A far better solution would be to create your owntruststore, starting with a copy of the cacertsfile, and specifically tell Java to use that one via the system property javax.net.ssl.trustStore.

更好的解决方案是创建您自己的信任库,从cacerts文件的副本开始,并特别告诉 Java 通过系统属性使用该信任库javax.net.ssl.trustStore.

You should make building this part of your build process, so as to keep up to date with changes I the cacertsfile caused by JDK upgrades.

您应该将构建这部分作为构建过程的一部分,以便及时了解cacerts由 JDK 升级引起的文件更改。

回答by Mohammed Irfan Tirupattur

If you are using Eclipse just cross check in Eclipse Windows--> preferences---->java---> installed JREsis pointing the current JRE and the JRE where you have configured your certificate. If not remove the JRE and add the jre where your certificate is installed

如果您使用的是 Eclipse,只需在 Eclipse Windows--> 首选项--> java ---> 安装的 JRE 中交叉检查当前 JRE 和您配置证书的 JRE。如果没有删除 JRE 并在安装证书的位置添加 jre

回答by acohen

In my case the issue was resolved by installing Oracle's official JDK 10as opposed to using the default OpenJDK that came with my Ubuntu. This is the guide I followed: https://www.linuxuprising.com/2018/04/install-oracle-java-10-in-ubuntu-or.html

在我的情况下,问题是通过安装Oracle 的官方 JDK 10而不是使用我的 Ubuntu 附带的默认 OpenJDK 解决的。这是我遵循的指南:https: //www.linuxuprising.com/2018/04/install-oracle-java-10-in-ubuntu-or.html

回答by Ilya Lysenko

On Windowsyou can try these steps:

在 Windows 上,您可以尝试以下步骤:

  1. Download a root CA certificate from the website.
  2. Find a file jssecacerts in the directory /lib/securitywith JRE (you can use a comand System.out.println(System.getProperty("java.home");to find the folder with the current JRE). Make a backup of the file.
  3. Download a program portecle.
  4. Open the jssecacerts file in portecle.
  5. Enter the password: changeit.
  6. Import the downloaded certificate with porticle (Tools > Import Trusted Certificate).
  7. Click Save.
  8. Replace the original file jssecacerts.
  1. 从网站下载根 CA 证书。
  2. /lib/securityJRE所在的目录中找到一个文件jssecacerts (可以使用命令System.out.println(System.getProperty("java.home");查找当前JRE所在的文件夹)。备份文件。
  3. 下载程序portecle
  4. 在 portecle 中打开 jssecacerts 文件。
  5. 输入密码:changeit。
  6. 使用 porticle 导入下载的证书(工具 > 导入可信证书)。
  7. 单击保存。
  8. 替换原来的文件jssecacerts。