简体   繁体   English

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

[英]PKIX path building failed in Java application

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已安装 Java JDK 1.7.0_25
  2. Set system environment variable JAVA_HOME to C:\\Progra~1\\Java\\jdk1.7.0_25\\设置系统环境变量JAVA_HOMEC:\\Progra~1\\Java\\jdk1.7.0_25\\
  3. Imported the certificate into cacerts with keytool使用keytool将证书导入 cacerts
  4. Ensured that the certificate exists in keytool with -list .使用-list确保证书存在于keytool

I have tried to repeat step 3 with InstallCert to ensure that i havent messed anything up.我试图用InstallCert重复步骤 3 ,以确保我没有搞砸任何事情。

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")); 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.keyStore"));

returns null .返回null

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:确定根 CA 证书:

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

    in this case we find the root CA is Equifax Secure Certificate Authority在这种情况下,我们发现根 CA 是Equifax Secure Certificate Authority

  2. Download root CA cert .下载根 CA 证书
  3. Verify downloaded cert has proper SHA-1 and/or MD5 fingerprints by comparing with info found here通过与此处找到的信息进行比较,验证下载的证书是否具有正确的 SHA-1 和/或 MD5 指纹
  4. Import cert for javax.net.ssl.trustStore :javax.net.ssl.trustStore导入证书:

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

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 cacerts file 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.为了清楚起见,并解决下面评论中的误解,您需要将证书导入到您打算使用的 JREcacerts文件中,并且很少会在 JDK 内部传送该证书,因为客户端通常不会有 JDK。 Anything in the commentary below that suggests otherwise should be ignored as not expressing my intention here.以下评论中任何暗示其他内容的内容都应该被忽略,因为这里没有表达我的意图。

A far better solution would be to create your own truststore, starting with a copy of the cacerts file, and specifically tell Java to use that one via the system property javax.net.ssl.trustStore.更好的解决方案是创建您自己的信任库,从cacerts文件的副本开始,并通过系统属性javax.net.ssl.trustStore.专门告诉 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 cacerts file caused by JDK upgrades.您应该将构建这部分作为构建过程的一部分,以便与 JDK 升级引起的cacerts文件的更改保持cacerts

If you are using Eclipse just cross check in Eclipse Windows--> preferences---->java---> installed JREs is pointing the current JRE and the JRE where you have configured your certificate.如果您使用的是 Eclipse,只需在 Eclipse Windows--> 首选项--> java ---> 安装的 JRE 中交叉检查当前 JRE 和您配置证书的 JRE。 If not remove the JRE and add the jre where your certificate is installed如果没有删除 JRE 并在安装证书的位置添加 jre

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

On Windows you can try these steps:在 Windows 上,您可以尝试以下步骤:

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

In my case the issue was resolved by installing Oracle's official JDK 10 as opposed to using the default OpenJDK that came with my Ubuntu.在我的情况下,问题是通过安装Oracle 的官方 JDK 10而不是使用我的 Ubuntu 附带的默认 OpenJDK 解决的。 This is the guide I followed: https://www.linuxuprising.com/2018/04/install-oracle-java-10-in-ubuntu-or.html这是我遵循的指南: https : //www.linuxuprising.com/2018/04/install-oracle-java-10-in-ubuntu-or.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM