Master-slave
发布于 2019-09-20 / 11 阅读
0
0

HttpClient POST请求异常:peer not authenticated

前言

在做一个和第三方系统的API对接的需求时,使用HttpClient 4.2.1发送API请求并接收返回数据。代码在开发环境正常运行但是在安装包环境中无法取得正确的返回值,日志报错Peer not authenticated,前后花了比较久的时间定位和解决问题。

定位问题

  1. 因为是打jar包替换到安装包的方式进行替换的,所以先确认更新到安装包中的文件是最新的,确认发现没有问题。

  2. Google “Peer not authenticated”,发现网上很多解决方法都是设置SSLScoketFactory,X509TrustManager来解决,尝试使用其中的代码但是并没有解决问题。

  3. 尝试替换安装包中jre/lib/security下的local_policy.jar,US_export_policy.jar也不能解决问题。

  4. 后来在调试代码的过程中无意发现同事开发的时候因为切换了新的代码但是没把开发环境换回来所以用的JDK1.8,但是安装包里是JDK1.7(心累)。然后将运行环境重新换成了JDK1.7,果然问题在开发环境也出现了。

环境不一致导致的问题找到了,但是为什么新版的JDK可以正常运行老版的不行,应该是某个版本升级了什么功能导致的,但跨度这么大总不能直接去查文档吧。仔细一想可能是HTTPS的问题,HTTPS无非就是证书和加密方式嘛,于是在Chrome里点开对接的网站证书

看到根证书++DST Root CA X3++比较高端,会不会就是它的问题,又经过一番搜索终于有了发现

↑↑↑SSL “Peer Not Authenticated” error with HttpClient 4.1↑↑↑

总的来说就是如果服务器的证书是自己发的,需要先把这个证书加到keystore里面信任(这里肯定不是这个问题)。但如果是比较知名的机构签发的,那可能就是主流浏览器支持的证书远范围大于JDK/JRE已经提供的,导致浏览器能看到是HTTPS的,但是JDK/JRE不认可。所以就出现了这个问题。

↑↑↑SSL certs in Java↑↑↑

再接下来在Letsencrypt的社区看到了在 JDK_7u111 和 JDK8U_101的版本才支持“DST Root CA X3”,开发用到的版本正是JDK7u67,至此问题算是找到了。

解决方法

既然是JDK版本的问题,那直接使用更新的JDK版本就行了,在一番挣扎(搜索、自己编译)后还是弄不到JDK_7u111(Oracle已经停止了JDK_7u80版本之后的维护,收费才能拿到)版本的情况下,将目光转向了同事之前运行的时候用的JDK_8u221版本,替换了安装包内的JRE环境,大功告成。

后记

后续我还尝试了通过在控制面板(JRE 里的javacpl.exe)里设置安全级别来看看能不能生效,但是并没有什么用。

尝试跟代码看看新的改动加在了哪里,因为太多也再仔细跟下去了,但是发现在创建Socket的过程中,使用JDK1.8的Socket比使用JDK1.7的CipherSuites多了很多支持,如TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384等256位的加密算法,这些算法应该需要其他jar包的支持,可能这也是在3中替换两个jar包无效的原因吧。

PS:还好Tomcat7支持这个版本的JDK😄


评论