Https接口请求异常
一. 问题现象
wolves在接入个启DSP渠道时,后端请求转化回调https接口时,返回异常:javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure,但是请求其他渠道的https接口却是正常的
二. 解决过程
2.1 了解https
HTTPS并不是一个单独的协议,而是对工作在一加密连接(TLS或SSL)上的常规HTTP协议的称呼。
TLS 与 SSL
SSL 是 TLS 的前身。SSL 是 Netscape 公司推出的 HTTPS 协议,以 SSL 进行加密。
IETF 将 SSL 进行标准化,公布了第一版的 TLS 标准文件。
发展历史
SSL
- 1.0 没有公开过
- 2.0 1995年2月发布
- 3.0 1996年发布。2014年10月,Google 发现 SSL 3.0 设计缺陷,建议禁用此一协议。
TLS
- 1.0
- 1.1 2006
- 1.2 2008
- 1.3 2016
JDK中对 HTTPS 版本的支持情况
JDK 6
- SSL v3
- TLS v1(默认)
- TLS v1.1(JDK6 update 111 及以上)
JDK 7
- SSLv3
- TLS v1(默认)
- TLS v1.1
- TLS v1.2
JDK 8
- SSL v3
- TLS v1
- TLS v1.1
- TLS v1.2(默认)
2.2 大胆怀疑,小心求证
对方接口有问题
- 怀疑原因:其他https接口ok,只有这个https接口抛异常,怀疑对方接口有问题
- 求证:通过在服务器上执行curl,结果正常返回
- 结论:对方接口没问题
TLS协议不一致
怀疑原因:客户端和服务端https的TLS协议不一致,原因是之前爱思渠道遇到过TLS协议不一致的问题,导致无法接收到点击请求
求证:
- wolves使用jdk版本为1.8.0_141,默认支持TLS v1.2
- 对方支持TSL v1.0 、v1.1、 v1.2
- 通过如下方式设置TLS版本,还是抛异常
java 请求前设置https.protocols System.setProperty("https.protocols", "TLSv1.1, TLSv1.2");
结论:不是协议版本不一致问题
怀疑jdk版本有问题
- 怀疑原因:本地通过main方法执行可以,但是在开发环境不行
- 本地环境版本:1.8.0202,开发环境版本:1.8.0141
- 求证:
- 通过测试环境,使用JDK 1.8.0_141的镜像发布,同样抛异常
- 根据博客https://www.oschina.net/question/2282830247657?sort=default&p=1,在开发环境替换新jar包后,问题解决,印证JDK 1.8.0141有问题
- 通过测试环境,使用JDK 1.8.0261的镜像,问题解决。再次印证JDK 1.8.0141有问题。
- 结论:JDK版本问题,具体原因参考:https://blog.51cto.com/zpf666/2341494?source=dra
- 解决方案:eone上容器使用镜像”jdk8u261tomcat7.0.53v2“
- 参考资料:https://myssl.com/,该网站可以监测https协议是否存在问题
作者介绍
- 孙景亮 资深服务端开发工程师