PKIX path building failed,SunCertPathBuilderException: unable to find valid certification path to requested target报错和解决
背景:有一个项目,需要调用gitlab的api,开发阶段在windows上进行。开发完成部署到linux中时,当请求gitlab接口的时候报如下错误:
2023.03.22 10:30:39.522 ERROR [http-nio-8089-exec-2] org.apache.juli.logging.DirectJDKLog 181 log - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request process ing failed; nested exception is org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://gitlab.xxx.cn/oauth/token": sun.security.validator.ValidatorException: PKI X path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; nested exception is 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] with root cause sun .security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) ~[?:1.8.0_251] at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) ~[?:1.8.0_251] at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280) ~[?:1.8.0_251] at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:445) ~[?:1.8.0_251] at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:317) ~[?:1.8.0_251] at sun.security.validator.Validator.validate(Validator.java:262) ~[?:1.8.0_251] at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:330) ~[?:1.8.0_251] at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:227) ~[?:1.8.0_251] at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:132) ~[?:1.8.0_251] at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1671) ~[?:1.8.0_251] at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:226) ~[?:1.8.0_251] at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1082) ~[?:1.8.0_251] at sun.security.ssl.Handshaker.process_record(Handshaker.java:1010) ~[?:1.8.0_251] at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1079) ~[?:1.8.0_251] at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1388) ~[?:1.8.0_251] at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1416) ~[?:1.8.0_251] at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1400) ~[?:1.8.0_251] at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559) ~[?:1.8.0_251] at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) ~[?:1.8.0_251] at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:167) ~[?:1.8.0_251] at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:78) ~[spring-web-4.3.4.RELEASE.jar!/:4.3.4.RELEASE] at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48) ~[spring-web-4.3.4.RELEASE.jar!/:4.3.4.RELEASE] at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53) ~[spring-web-4.3.4.RELEASE.jar!/:4.3.4.RELEASE] at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:619) ~[spring-web-4.3.4.RELEASE.jar!/:4.3.4.RELEASE] at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:580) ~[spring-web-4.3.4.RELEASE.jar!/:4.3.4.RELEASE] at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:380) ~[spring-web-4.3.4.RELEASE.jar!/:4.3.4.RELEASE]
经过了解,原因是linux上没有相关的ssl证书,需要导入
1 导出windows的证书
我们访问需要导出证书的网站
看到如下信息,我们分别导出这3级证书
得到如下文件
- DigiCert Global Root CA.crt
- GeoTrust CN RSA CA G1.crt
- _.gxxxics.cn.crt
这三个文件备用
2 查看linux证书
参考:https://www.shuzhiduo.com/A/lk5abmgPd1/
系统是ubuntu,证书存储位置为 /usr/share/ca-certificates/mozilla 并且,我们发现其中一个证书已经存在了,我们只需导入另外的两个
需要安装CA证书我们只需要将其放在”/usr/share/ca-certificates”目录或其子目录下,ca-certificates工具就能自动扫描到。为了不与其它根证书混淆,我们创建一个子目录名为”extra”。然后将待安装的证书拷贝到这里
然后使用如下命令安装证书
sudo dpkg-reconfigure ca-certificates
会看到如下页面
继续
按空格键选中,enter回车键保存,看到如下信息,说明证书安装成功
genomics@SZBGIPS7872A:/usr/share/ca-certificates/extra$ sudo dpkg-reconfigure ca-certificates Updating certificates in /etc/ssl/certs... rehash: warning: skipping ca-certificates.crt,it does not contain exactly one certificate or CRL 2 added, 0 removed; done. Processing triggers for ca-certificates (20211016ubuntu0.18.04.1) ... Updating certificates in /etc/ssl/certs... 0 added, 0 removed; done. Running hooks in /etc/ca-certificates/update.d... updates of cacerts keystore disabled. done. genomics@SZBGIPS7872A:/usr/share/ca-certificates/extra$
此时,证书已经安装到了linux中,但是java代码中还是会报错,请接着往下看
3 jdk安装证书
到我们的jdk安装目录,有如下工具 /data/jdk1.8.0_251/bin/keytool 我们使用这个工具安装证书到jdk的cacerts文件中
sudo ./keytool -import -keystore /data/jdk1.8.0_251/jre/lib/security/cacerts -file /usr/share/ca-certificates/extra/GeoTrust_CN_RSA_CA_G1.crt Enter keystore password: Certificate was added to keystore genomics@SZBGIPS7872A:/data/jdk1.8.0_251/jre/bin$
如果需要输入密码,我们输入默认密码changeit即可
,然后,接下来,我们需要重启一下我们的jvm应用。
搞定
4 后记
后来换了一台windows电脑,同样出现了PKIX path building failed,SunCertPathBuilderException: unable to find valid certification path to requested target报错。
看来windows系统上,jdk证书中也需要添加_.gxxxs.cn.crt
打开命令行,以管理员身份运行
cd到cd C:\Program Files\Java\jdk1.8.0_211\bin
命令:
C:\Program Files\Java\jdk1.8.0_211\bin>keytool.exe -import -keystore "C:\Program Files\Java\jdk1.8.0_211\jre\lib\security\cacerts" -file "E:\software\chrome\_.gexxxs.cn.crt"
提示输入秘钥口令:输入changeit
是否信任此证书,y,回车
ok了