证书配置不当导致的网页正常但Java无法访问接口报错SSLHandshakeException PKIX path building failed

介绍

网站项目中一个重要的泛域名证书过期后, 由于更换了域名的托管服务商, 需要重新通过acme.sh配置申请信息,网站重新配置新的证书后仍然无法使用Java调用对应接口。

报错 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

但是通过浏览器是能够正常访问网页且不会报证书相关的错误的,后续发现是配置的证书链不完整导致的。

流程

问题流程复现如下。

重新申请了证书

网站证书过期后,更换了域名的服务商,为了防止旧的acme.sh配置影响后续的续期,直接删除了现有已过期的证书。

完成证书申请后获得了包含域名命名(此处以example.com举例)的下列文件:

1
2
3
4
5
6
7
ca.cer # CA证书
fullchain.cer # 完整链证书(CA+域名)
example.com.cer # 域名证书
example.com.key # 私钥
example.com.csr
example.com.conf
example.com.csr.conf

错误配置

删除了旧Nginx的TLS配置后,自认为现在可以直接使用域名证书,进行了如下的重新配置。

1
2
ssl_certificate /usr/local/ssl/example.com.cer;
ssl_certificate_key /usr/local/ssl/example.com.key;

完成以上操作后执行并重启了服务。

问题发生

更换完续期后的证书,API接口仍然无法通过Java访问,报错PKIX path building failed,但是通过浏览器是能够正常访问网页且不会报证书相关的错误的。

遂通过网络搜索相关问题的解决方案,大多数是建议将证书存入本地的信任存储、或者直接忽略证书验证。这样对于一个登录接口显然是不安全的。

最终解决

经过仔细的检查,旧的配置使用的是完整链(包含CA),将配置文件中的证书路径指向fullchain.cer,重启服务后,恢复正常。

1
2
ssl_certificate /usr/local/ssl/fullchain.cer;
ssl_certificate_key /usr/local/ssl/example.com.key;

结论

申请的证书在设置时推荐使用完整链的证书文件,如本文中提到的fullchain.cer

总而言之,浏览器可能忽略了一些东西,导致现在即使不包含CA,浏览器也不会认为有问题。

正常跑的代码突然出错了,先相信你的代码没有写错,再去排除问题。


证书配置不当导致的网页正常但Java无法访问接口报错SSLHandshakeException PKIX path building failed
https://swai.top/2023/10/03/x509failed/
作者
ShallowAi
发布于
2023年10月3日
许可协议