项目中需要请求外部https的接口,由于项目的特殊性,采用比较通用的RestTemplate进行调用,在本地开发环境调试通过的,部署到服务器上却提示证书无法识别,具体报错信息如下(已屏蔽掉无关堆栈):

org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://xxx.xxx.com/xxx/api/xxx": sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; nested exception is 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 targetat org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:744)at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:670)at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:608)
……at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:684)
……at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295)at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
……at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:56)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:55)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
……at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:96)at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:155)at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:123)at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:108)at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806)at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)at java.lang.Thread.run(Thread.java:748)
Caused by: 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 targetat sun.security.ssl.Alerts.getSSLException(Alerts.java:192)at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1946)at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:316)at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:310)at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1639)at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223)at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:436)at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:384)at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:374)at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393)at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:87)at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:735)... 167 common frames omitted
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested targetat sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:397)at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302)at sun.security.validator.Validator.validate(Validator.java:262)at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1621)... 190 common frames omitted
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested targetat sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392)... 196 common frames omitted

尝试通过关键字unable to find valid certification path to requested target在网上搜索,目前网上搜索的解决方案不外乎两类:
1、将访问地址的证书通过浏览器保存,然后通过jdk的keytool导入;
2、在程序中设置ssl忽略。
为了安全方面考虑,我们先不考虑证书忽略的方案,转而考虑方案一,试验了两台服务器,将证书导入,均不成功,服务器环境的jdk版本如下:

java version "1.8.0_202"
Java(TM) SE Runtime Environment (build 1.8.0_202-b08)
Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)

系统版本为:CentOS Linux release 7.4.1708 (Core)

而本地开发环境的jdk信息为:

java version "1.8.0_31"
Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)

服务器jdk的小版本比本地高,说明不是API函数库的问题,问题的核心还是在证书的验证过程。
通过抓包发现在https握手过程中出现了无法识别证书(46)的错误:

结合之前总结过的https的握手过程,这一步应该是客户端向服务端请求了证书的颁发机构,然后与本地证书机构列表去比对,如果存在则视为合法,否则视为非法。
通过keytool -list 获取证书列表,发现服务器只有默认的一条,而本地jdk的证书列表则有几十条之多,说明本地的受信任列表更加充分,服务器端则有限,如今证书的颁发机构有很多,出现服务器的jdk无法识别的情况也就不足为奇了。

既然知道了问题所在,而且在尝试了导入请求地址的证书未果之后,想到能否直接将本地的cacerts文件拷贝到服务器上替换呢。
先将服务器端的证书文件备份,jdk1.8的证书文件为$JAVA_HOME/jre/lib/security/cacerts,然后本地的cacerts传输到服务器端覆盖。
重新启动java应用,再次测试,没有再提示证书错误了,请求顺利通过,也收到了服务器端的正确返回。
自此,我们在尝试了网上的方法无果后,另辟蹊径通过直接拷贝成功请求的cacerts证书文件完美的解决了问题。

希望此文对于像我一样拥有强迫症的朋友有所帮助。

https无法识别证书(unable to find valid certification path to requested target)的另类解法相关推荐

  1. Spring Boot项目中使用RestTemplate调用https接口出现 unable to find valid certification path to requested target

    问题描述:Spring Boot项目中使用RestTemplate调用https接口出现以下错误: PKIX path building failed: sun.security.provider.c ...

  2. 【已解决】Https请求报错:unable to find valid certification path to requested target

    SSL认证失败: 报错信息如下: sun.security.validator.ValidatorException: PKIX path building failed: sun.security. ...

  3. Https请求报错:unable to find valid certification path to requested target

    SSL认证失败: 报错信息如下: sun.security.validator.ValidatorException: PKIX path building failed: sun.security. ...

  4. JAVA 证书信任 :unable to find valid certification path to requested target

    最近使用 gradle 配置阿里云的maven代理仓库:https://maven.aliyun.com/repository/public 构建的时候遇到:unable to find valid ...

  5. HttpClient发送Https请求报 : unable to find valid certification path to requested target

    一.场景   近期在对接第三方接口时,通过HttpClient发送Https请求报 : unable to find valid certification path to requested tar ...

  6. JAVA 解决 unable to find valid certification path to requested target 证书认证

    JAVA 解决 unable to find valid certification path to requested target 证书认证 下载证书 导入证书 更新证书 其他命令 下载证书 点击 ...

  7. jenkins设置清华镜像时报错 unable to find valid certification path to requested target

    jenkins在设置清华镜像时,会报找不到证书的错,具体报错内容: 检查更新中心: SSLHandshakeException: sun.security.validator.ValidatorExc ...

  8. 解决PKIX:unable to find valid certification path to requested target 的问题

    注意:本文出自"阿飞"的博客 ,如果要转载本文章,请与作者联系! 并注明来源: http://blog.csdn.net/faye0412/article/details/6883 ...

  9. IDEA运行报Command line is too long和unable to find valid certification path to requested target

    IDEA解决 Maven:unable to find valid certification path to requested target 一.报错信息: Could not transfer ...

  10. 【SSL】调用HTTPS://服务遇到错误:unable to find valid certification path to requested target

    前言 OkHttpClient 最近有个需求,需要调用一个https开头的URL服务. 服务方提供了一个demo,但,demo是调用http的服务. 网上找了一大圈,发现盖起来要这样要那样的.都不符合 ...

最新文章

  1. 关于IO模拟时序(SPI)的注意事项
  2. self-attention竟然没用?
  3. 构造类斐波那契数列矩阵
  4. Redis架构及分片管理
  5. VSTS TFS 强制删除签出锁定项 解除 锁定
  6. 爬虫养成记 - urllib2的调试和错误处理
  7. H3C DHCP实验
  8. saltstack安装使用
  9. 基于Web的酒店客房管理系统的设计与实现
  10. Linux和windows导入scv数据文件
  11. POI使用详解 java 复杂excel导出(笔记)
  12. 正则表达式的‘前瞻后顾’
  13. 同学们上课,今天我们学习:UI 操作一定要在 UI 线程吗?
  14. 关于Excel自定义TEXTJOIN函数、SWITCH函数
  15. X3D代码理解之demo(cfg)
  16. 【Android SDM660源码分析】- 01 - 如何创建 UEFI XBL Protocol DXE_DRIVER 驱动及UEFI_APPLICATION 应用程序
  17. zedgraph绘图(修改)
  18. 微软发布免费的文件恢复工具
  19. 微信群创意活动_一小群制造商将大创意转变为用户社区
  20. protect java_java中的protect用法介绍

热门文章

  1. python+opencv简单人脸识别(源码)(有手就行)
  2. 机器学习与深度学习资料
  3. Vue.js(九) 第三方常用插件
  4. 基于单片机24V直流无刷电机电动车控制器设计
  5. vs2015安装msdn_visual studio 2015离线版msdn下载和安装图文教程
  6. NGFF(M.2) m.2中Bkey接口Mkey接口有什么不同
  7. autohotkey循环
  8. java实现word转pdf文件下载
  9. 网络蜘蛛采用三种策略来决定抓取网页的先后顺序
  10. 美图秀秀计算机教程,美图秀秀怎么抠图 美图秀秀抠图详细教程