升级服务后只支持TLS1.2,JDK1.7默认TLS1.0,调用为何失败?

摘要:背景 如标题所说,我手里维护了一个重要的老项目,使用jdk1.7,里面对接了很多个第三方服务,协议多种多样,其中涉及httphttps的,调用方式也是五花八门,比如:commons-httpclient、apache httpclient
背景 如标题所说,我手里维护了一个重要的老项目,使用jdk1.7,里面对接了很多个第三方服务,协议多种多样,其中涉及http/https的,调用方式也是五花八门,比如:commons-httpclient、apache httpclient、原生的url.openConnection()等。 <dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.0</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.3</version> </dependency> 最近,其中一个服务方,因为网络设备要加固、网络安全等原因,准备不再支持https的sslv3、tls1.0、tls1.1了,只支持tls1.2和tls1.3. 这边服务方也比较猛,直接就升级了,升级后没一会,他观察影响到我们这边的调用了,又回退了。 目前就是希望我们这边,作为客户端,先升级到tls1.2,即:调用他们服务的时候,使用tls1.2去调用。 本来我也不想动,你个服务端,安安心心地兼容下tls1.0、tls1.1,不是简单的很吗,最终拉扯了一顿,行吧,那就我们先研究下,看看好不好升级到tls1.2。如果实在不好弄,到时候直接改成http调用得了,搞啥https? 研究下来的方案,感觉还凑合,然后就改了,已经提交测试了,今天就先记录一下。 报错现象 我在网上找了个工具,可以测试目标https网站,支持哪几个版本的tls,如下所示,-p指定端口,后面的www.baidu.com就是目标ip或者域名。 https://nmap.org/ nmap --script ssl-enum-ciphers -p 443 www.baidu.com 比如上图的百度,就还在兼容老版本。 我在网上又试了几个域名,找到了一个只支持tls1.2的。 blog.csdn.net 下面,我们就拿blog.csdn.net举例,看看用tls1.0发送请求,会报什么错: 可以看到,当我们三次握手完成,发送了第一个ssl握手消息(client hello,版本为tlsv1)后,对方(blog.csdn.net)直接来了个Alert,然后服务端就主动断开socket了。这,连接都建不起来,还怎么消息交互呢,自然是所有调用全部失败。 报错代码debug sslcontext获取 给大家看下我们这边调用发起的代码,这个代码就是用的上面说的那个commons-httpclient包,这个包算是apache早期维护的http调用工具,后来慢慢就重心不在这里了,转到了apache httpclient。 https://hc.apache.org/httpclient-legacy/ HttpClient httpClient = new HttpClient(); httpClient.getParams().setContentCharset(charset); httpClient.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(0,false)); // 1 根据url,生成要调用的http method PostMethod httpMethod = new PostMethod(urlPath); try { long t1 = System.currentTimeMillis(); // 2 实际发起调用 int statusCode = httpClient.executeMethod(httpMethod); long spendTime = System.currentTimeMillis() - t1; ... } 从前面报错的原因看来也是挺清晰的,那就是看怎么改了。
阅读全文