Java中调用https报证书不存在问题的解决方案
Java中调用https报证书不存在问题的解决方案
报错现象
后台日志中有如下报错信息:
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid >certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:439)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:306)
at sun.security.validator.Validator.validate(Validator.java:271)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:312)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:221)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:128)
at sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:636)
... 76 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
问题原因
当我们使用Java去进行https的调用时,Java需要对服务端的证书进行认证,如果这个证书不在JDK的授信证书链名单内,那JDK就无法对该服务器证书进行认证,就会导致证书认证失败。
解决办法,在JDK中授信证书列表中添加请求服务器端的证书
命令在bash中执行,windows cmd中第一步可以用浏览器,第二步 $JAVA_HOME 改为 %JAVA_HOME%:
- 获取所访问的SSL站点服务端证书为 xxx.cert,其中127.0.0.1:8443改为实际的网站地址(也可以在浏览器中导出证书):
echo -n | openssl s_client -connect 127.0.0.1:8443 | sed -ne'/BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > xxx.cert
- 将获取的服务端证书链加入到JDK授信证书列表中(keytool是JDK中的标准命令,所以,需要先把JDK的bin目录添加到path中,或者使用 $JAVA_HOME/bin/keytool 进行调用):
keytool -importcert -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit -alias xxx -file xxx.cert
这样,就可以把xxx.cert中的证书信息导入到JDK的授信证书列表cacerts中了。
其他参考命令
- 查看:
keytool -list -v -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit -alias xxx
- 删除:
keytool -delete -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit -alias xxx