出现问题
ehr推送招聘需求单给moka的接口,昨天突然报网络错误
查看日志如下报错
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
排查原因
联系供应商moka后,得知他们在前几天更新了ssl证书,新证书的签发根证书与原来不一样,新证书采用了DigiCert Global Root G2签发
而我们的应用使用的是虚拟机,机器中的jdk(版本号为1.8.60)中没有这个证书,自带的证书是DigiCert签发的。所以调用供应商的api,就会报证书验证不通过。
所以只要调用的接口方一旦更新了证书,签发根证书与原来不一样,就会有这个问题。 而我们其他应用使用的是容器,容器中jdk版本是1.8.251,里面的证书是最新的,不会有这个问题
解决方案
供应商解决方案
供应商给了解决方案,就是自己下载一个新的根证书 blog.csdn.net/chaishen100…
公司内部解决方案
查询了公司的wiki,发现之前也有业务遇到过此问题
这种异常一般是证书问题,需要将证书给客户,客户重新导入证书。
证书导入方式:
登录Tomcat所在的机器,切换到目录 ${JAVA_HOME}/jre/lib/security, 执行如下命令:
keytool - import -alias tongdun -keystore cacerts -file ${JAVA_HOME}/jre/lib/security/*.tongdun.cn.cer
其中:
-alias 指定别名(推荐和证书同名)
-keystore 指定存储文件(此处固定)
-file 指定证书文件全路径(证书文件所在的目录)
注意:当切换到 cacerts 文件所在的目录时,才可指定 -keystore cacerts, 否则应该指定全路径;
此时命令行会提示你输入cacerts证书库的密码,敲入changeit即可,这是java中cacerts证书库的默认密码,当然也可自行修改。
可使用如下命令查看证书信息:
keytool -list -keystore cacerts -alias tongdun
如需更新证书,应先删除原证书,再导入新证书:
cd ${JAVA_HOME}/jre/lib/security
keytool -delete -alias tongdun -keystore cacerts
keytool -import -alias tongdun -keystore cacerts -file ${JAVA_HOME}/jre/lib/security/*.tongdun.cn.cer
keytool -list -keystore cacerts -alias tongdun
自己的解决方案
上面两种方案都没有去尝试,和同事商量后,我们使用了最简单的方案,从下面这个图里,我们看到jdk1.8.0_131以上就已经支持了这个证书,那么只要把我们容器服务器里的jdk证书文件来替换虚拟机jdk的证书文件不就行了?
jdk的证书目录如下,/usr/install/jdk1.8.0_60/jre/lib/security下的cacerts
然后复制高版本下的cacerts文件替换后,重启服务,问题真的就解决了!
补充一下根证书相关知识
首先,我们网站如果使用https,就需要申请证书。那么客户端如何知道这个证书是合法的呢?这里就引入了证书颁发者这个权威机构。这些机构会生成一些根证书,然后通过根证书去签发普通证书。客户端会通过根证书去校验网站上的证书是否合法。如果根证书不存在,那就直接认为网站证书非法。根证书会在设备(windows系统/Android系统等)出产时内置在系统中。
跟普通证书一样,根证书也会有过期时间。上面遇到的问题就是DigiCert老的根证书即将过期(2025年),如果继续用老的根证书签发会存在风险。所以DigiCert强制启用了新的根证书(新的根证书其实是2013年签发的,所以按理说2013年之后的设备都会包含这个根证书,但不过jdk在1.8.131之后才内置了这个根证书,可以说比较晚了)。