[英]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:程序,流程:
JAVA_HOME
to C:\\Progra~1\\Java\\jdk1.7.0_25\\
JAVA_HOME
为C:\\Progra~1\\Java\\jdk1.7.0_25\\
keytool
keytool
将证书导入 cacertskeytool
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 的解决方案示例
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
Import cert for javax.net.ssl.trustStore
:为
javax.net.ssl.trustStore
导入证书:
keytool -import -alias gmail_imap -file Equifax_Secure_Certificate_Authority.pem
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.为了清楚起见,并解决下面评论中的误解,您需要将证书导入到您打算使用的 JRE的
cacerts
文件中,并且很少会在 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 上,您可以尝试以下步骤:
/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./lib/security
找到一个文件 jssecacerts(您可以使用命令System.out.println(System.getProperty("java.home");
找到包含当前 JRE 的文件夹)。备份文件。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.