PKIX path building failed,SunCertPathBuilderException: unable to find valid certification path to requested target报错和解决

发布时间 2023-03-22 21:17:25作者: zhenjingcool

背景:有一个项目,需要调用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安装证书

参考:https://stackoverflow.com/questions/21076179/pkix-path-building-failed-and-unable-to-find-valid-certification-path-to-requ

到我们的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$

,然后,接下来,我们需要重启一下我们的jvm应用。

搞定