一 问题描述
我们暴露给外部系统调用的https接口,发生了
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
报错,但是我们系统配置的ssl在网页显示的是“证书是安全的”、“有效”。
异常信息如下:1
2
3
4
5
6
72021-04-02 16:04:15.348 ERROR 97788 --- [nio-8082-exec-1] c.e.p.z.w.controller.ExceptionAdvice : 未知异常
org.springframework.web.client.ResourceAccessException: I/O error on GET request for "https://xxx.com": sun.security.validator.ValidatorException: PKIX 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
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:744) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:670) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:311) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
....
二 原因查找与分析
首先,我们先去百度和Google找了很多同类问题,但是无一例外,都是因为自签的SSL,程序无法识别才报了 PKIX path building failed
错误,明细和我们的情况不同,我们的证书是全球第二大证书颁发机构Geotrust SSL Certificate颁发的,按理说不会出现证书的一些低级错误。更加不可能说java的HttpClient无法识别根证书的问题。
那么最大的可能就是我们Nginx的证书配置的有问题,最大可能是少了一些证书的配置。
于是找了运维要了我们域名下的所有证书,跟目前Nginx上配置的证书比对,发现确实缺了一个证书,正是CA证书,也就是缺了这个证书,在代码里无法识别根证书,从而无法校验证书。
证书解压目录如下
1 | $ ls -l |
然后查看我们服务器的证书仅包含其中的 star_xxx_com.crt
,即CA证书并未包含到证书里。
于是把DigiCertCA.crt
证书copy出来追加到了我们的nginx服务器证书/usr/local/nginx/ssl/xxx.com.crt
里
附Nginx证书配置:
1 | ssl_certificate /usr/local/nginx/ssl/xxx.com.crt; |
重启nginx
问题得以解决。