证书配置不当导致的网页正常但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 | |
错误配置
删除了旧Nginx的TLS配置后,自认为现在可以直接使用域名证书,进行了如下的重新配置。
1 | |
完成以上操作后执行并重启了服务。
问题发生
更换完续期后的证书,API接口仍然无法通过Java访问,报错PKIX path building failed,但是通过浏览器是能够正常访问网页且不会报证书相关的错误的。
遂通过网络搜索相关问题的解决方案,大多数是建议将证书存入本地的信任存储、或者直接忽略证书验证。这样对于一个登录接口显然是不安全的。
最终解决
经过仔细的检查,旧的配置使用的是完整链(包含CA),将配置文件中的证书路径指向fullchain.cer,重启服务后,恢复正常。
1 | |
结论
申请的证书在设置时推荐使用完整链的证书文件,如本文中提到的fullchain.cer。
总而言之,浏览器可能忽略了一些东西,导致现在即使不包含CA,浏览器也不会认为有问题。
正常跑的代码突然出错了,先相信你的代码没有写错,再去排除问题。