前言
最近因为uat环境https过期,后边进行证书续期,发现通过浏览器访问可以正常访问,但是接口调用该地址,却出现
unable to find valid certification path to requested target
网上的大部分针对java解决方案可以归类如下两种
1、在jdk证书库里添加该域名的公钥证书
注: 该方案比较繁琐,此外我们的接口不仅是要提供给java系语言,还要提供给其他非java系语言调用,其次因为我们的证书并非自签发,而是真金白银买的,理论上不应该有问题。所以该方案一开始就没纳入我重点考虑范围内
2、忽略证书认证,信任所有请求链接
该方案其实也不可取,因为有安全隐患,不过该方案确实能解决问题
对上述两种方案的具体落地方案,感兴趣的朋友可以查看如下链接
https://yiyige.blog.csdn.net/article/details/116049218
排查思路
我们通过postman调用,发现接口调不通,然后postman那边有个提示让我们禁用ssl校验,禁用掉确实能访问。
后来我们通过curl访问,出现如下提示
圈红的意思是证书的颁发者无法识别,那就大体可以说明我们证书确实出了点问题。
接着我们做了这么一件事,我们将uat环境https证书和可以正常访问的https证书做了个对比
我们uat的证书形如下
正常访问的证书形如下
大家一眼都可以看出问题了,我们UAT的证书少了一段内容,其实加上这段内容就构成了一个证书链。
证书链的相关科普介绍可以查看如下文章
https://www.anxinssl.com/9801.html
解决方案
因为之前运维提供给我们都是构成一个完整证书链的证书,而这次估计是太忙忘了,仅提供用户域名证书,仅仅这个证书是不够。后面我们找了运维要了完整证书资料
ca-bundle.crt 文件存储了各大证书颁发证的根证书交叉文件。我们需要ca-bundle.crt里面的内容追加到用户证书内容后面(即截图uat.crt)。示例
如果是linux环境,则可以执行文件合并操作命令
cat uat.crt ca_bundle.crt >> uat.crt
执行完后,将证书重新替换,问题就解决了。如果没有ca_bundle.crt,我们也可以通过浏览器(注: 从浏览器我们可以拿到完整的证书链),把相应的中间证书下载下来,追加到我们用户证书后面。
具体操作步骤(以360浏览器为例,其他浏览器大同小异)
1、点击浏览器旁边的小锁
2、点击证书信息,选择详细信息
3、将中间证书导出
4、将中间证书的内容追加到用户证书后面
注: 如果追加中间证书后,证书还是有问题,则按上步骤,把根证书下下来,再次追加到用户证书后面。
总结
整体的解决方案,就是将根证书、中间证书追加到用户证书后面,如果是自签发的证书,该方案就没法使用,就尝试一下其他方案。
另外推荐一下阿里的通义灵码,确实挺厉害。我们尝试让它解决一下上述问题
它提供的方案基本上可以满足我们要求