JDK8/17/21等从浏览器导入证书,解决报错:PKIX path building failed
手打不易,如果转摘,请注明出处!
注明原文:https://zhangxiaofan.blog.csdn.net/article/details/148254122
目录
背景
报错:PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:130) ~[na:na]
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:383) ~[na:na]
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:326) ~[na:na]
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:321) ~[na:na]
at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:647) ~[na:na]
at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:467) ~[na:na]
at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:363) ~[na:na]
at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:393) ~[na:na]
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:476) ~[na:na]
at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1273) ~[na:na]
at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1260) ~[na:na]
at java.base/java.security.AccessController.doPrivileged(AccessController.java:714) ~[na:na]
at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:1205) ~[na:na]
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) ~[na:na]
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate.lambda$executeTasks$3(SSLFlowDelegate.java:1134) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.HttpClientImpl$DelegatingExecutor.execute(HttpClientImpl.java:177) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate.executeTasks(SSLFlowDelegate.java:1129) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate.doHandshake(SSLFlowDelegate.java:1095) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader.processData(SSLFlowDelegate.java:494) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader$ReaderDownstreamPusher.run(SSLFlowDelegate.java:269) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$LockingRestartableTask.run(SequentialScheduler.java:182) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$TryEndDeferredCompleter.complete(SequentialScheduler.java:324) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:151) ~[java.net.http:na]
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:207) ~[java.net.http:na]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[na:na]
... 1 common frames omitted
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 java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:388) ~[na:na]
at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:271) ~[na:na]
at java.base/sun.security.validator.Validator.validate(Validator.java:256) ~[na:na]
at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:284) ~[na:na]
at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:144) ~[na:na]
at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:625) ~[na:na]
... 23 common frames omitted
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:148) ~[na:na]
at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:129) ~[na:na]
at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297) ~[na:na]
at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:383) ~[na:na]
... 28 common frames omitted
由于项目是内嵌的Apache HttpClient或OkHttp,项目不方便直接修改,所以需要手动管理证书(从浏览器导出、导入到JDK)。
如果你的项目是自己用Apache HttpClient或OkHttp,可以参考这篇文章来绕过证书检验:
检查项1—JDK17/21和JDK8的证书路径不同
JDK8: %JAVA_HOME%\jre\lib\security\cacert
JDK17:%JAVA_HOME%\lib\security\cacerts
JDK21:%JAVA_HOME%\lib\security\cacerts
检查项2—检查IDEA设置的JDK
- 打开 IntelliJ IDEA →
File→Project Structure→SDKs,检查JDK home path是否指向你添加证书的 JDK(如C:\Program Files\Java\jdk-17)。 - 如果配置了多个 JDK,确保项目实际运行的 JDK 是你修改过的版本。
检查项3—导出证书链不完整(关键)
使用浏览器访问目标接口的URL,导出完整的服务器证书(包括所有中间证书和根证书)

继续点击

注意导出证书的时候,需要导出完整的证书链,以及多个证书目录
为了避免出问题,我们要确保导入了所有 根证书(Root CA)或中间证书(Intermediate CA),就是说,只要出现在下面目录的,全部都导出一遍。
例如:证书有问题,尝试把下面3个目录全部导出一遍。这里我只导出了根目录(证书链)。

注意:一定要选择完整的根目录(最上面的)
注意:一定要选择完整的根目录(最上面的)
注意:一定要选择完整的根目录(最上面的)
导出后就可以去安装证书了,以JDK17为例:
导入证书
先进入到JDK证书路径
cd /d %JAVA_HOME%\lib\security
拷贝证书到当前路径,然后导入
keytool -keystore <truststore证书> -import -alias <导入证书别名> -file <导入的证书> -storepass changeit
例如:
keytool -keystore cacerts -import -alias Baidu -file baidu.crt -storepass changeit
查看证书
keytool -list -V -keystore <truststore证书> -storepass changeit -alias <证书别名>
例如:
keytool -list -V -keystore cacerts -storepass changeit -alias Baidu
删除证书
keytool -delete -keystore cacerts -alias <证书别名>
例如:
keytool -delete -keystore cacerts -alias Baidu
至此,手动管理的证书就成功导入JDK,运行项目再试试!!
更多推荐


所有评论(0)