HTTPS请求 Received fatal alert: handshake_failure异常---与众不同的原因
今天在项目遇到了Received fatal alert: handshake_failure 的问题,直译就是握手失败了,说实话,我也是第一次碰到这种情况。在各大论坛,各种技术博客的海洋里,仍然没有解决我的问题。最后捡漏发现了这个原因,真的太出乎意料了。
首先和大家说一下网上的一些经验和处理办法,算是一个总结。
我们用curl 和 postman 发送请求,都可以握手成功,唯独用代码不能请求成功。handshake_failure的原因绝不是一种。
原因一: Https 的协议版本不一致。协议有 TLSv1.2,TLSv1.1,SSLv3
如何来确定这个问题?
1:如果你是在本机运行,可以这么做,写一个通讯客户端(只用来测试握手的)
代码是我临时引用别人的,我的在服务器上不好拿下来。
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate; import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager; public class HttpsTest { private static class TrustAnyTrustManager implements X509TrustManager { @Overridepublic void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Overridepublic void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Overridepublic X509Certificate[] getAcceptedIssuers() { return null; } } private static class TrustAnyHostnameVerifier implements HostnameVerifier { public boolean verify(String hostname, SSLSession session) { return true; } } public static String sendHttps(String url) throws Exception { InputStream in = null; OutputStream out = null; String returnValue = ""; try { //SSLContext sc = SSLContext.getInstance("SSL");
// System.setProperty("https.protocols", "TLSv1.2,TLSv1.1,SSLv3");
// SSLContext sc = SSLContext.getInstance("TLS", "SunJSSE");SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom()); URL console = new URL(url); HttpsURLConnection conn = (HttpsURLConnection) console.openConnection(); conn.setSSLSocketFactory(sc.getSocketFactory());
// conn.setHostnameVerifier(new TrustAnyHostnameVerifier()); conn.setRequestMethod("POST");conn.connect(); InputStream is = conn.getInputStream(); DataInputStream indata = new DataInputStream(is); returnValue = indata.readLine(); conn.disconnect(); } catch (ConnectException e) { e.printStackTrace();throw e; } catch (IOException e) { e.printStackTrace();throw e; } finally { try { in.close(); } catch (Exception e) { } try { out.close(); } catch (Exception e) { } } return returnValue; } public static void main(String[] args) throws Exception { System.out.println(sendHttps("https://finance-23055.beta.qunar.com")); }
}
## 代码转载 https://blog.csdn.net/dzy_001/article/details/81012959
然后在运行参数里面设置
-Djavax.net.debug=all
然后运行,会出现下面的,内容很多,可以找到下面这些。
main, WRITE: TLSv1.2 Handshake, length = 191 ## 这是客户端发出的版本
[Raw write]: length = 196main, READ: TLSv1.2 Alert, length = 2 ## 这是服务端返回的版本
main, RECV TLSv1.2 ALERT: fatal, handshake_failure
很遗憾,这不能解决我的问题,因为客户端服务端都是TLSv1.2。如果你们发现这两个版本不一样的话,你就属于这种情况了,如何解决,请看其他文章吧,我就不细说了,给两个推荐。
http://www.voidcn.com/article/p-xjnaqnwd-bqu.html
https://blog.csdn.net/u014644574/article/details/83381303
2:服务器不支持此协议
SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
然后用openssl s_client -connect finance-23055.beta.qunar.com:443 -state -debug -tls1 -msg看到的message回复是这样:read from 0xb644fc0 [0xb689760] (5 bytes => 5 (0x5))
0000 - 15 03 01 00 02 …..
read from 0xb644fc0 [0xb689765] (2 bytes => 2 (0x2))
0000 - 02 28
其中0x15代表的是alert,而0x28代表的handshake failure
这样很难发现服务器的支持协议,很慢,还要猜,还可能猜不准
https://www.ssllabs.com/ssltest/
进入这个地址,输入你要测试的服务器地址。然后就会出一个报告,很详细。
协议很清楚 看出是否支持。下面还有更加详细的,自己试试 吧。
3:SSL算法不支持
curl -d "" -k https://IP:port/tests -v
使用上述命令,我们可以清晰看到执行过程。
其中有一行是这样的
SSL connection using ******** ## * 代表了curl使用的算法
这个算法我们就是我们的了。那看我们的程序 是否支持这种算法呢?
ctx.getSupportedSSLParameters().getCipherSuites()
ctx.getSocketFactory().getDefaultCipherSuites()
ctx.getSocketFactory().getSupportedCipherSuites()## ctx 是SSLContext 对象
打印一下,看curl的算法,是否在我们java的支持范围内。
解决办法请参考:https://blog.csdn.net/qq_36783371/article/details/80665901
4:也就是我这种了,最悲哀的吧。看我的上述代码了么,去掉这一段,就不会握手失败了。这个验证也是在握手过程内。
private static class TrustAnyHostnameVerifier implements HostnameVerifier { public boolean verify(String hostname, SSLSession session) { return true; } }
好了,这就是我总结的所有了。
HTTPS请求 Received fatal alert: handshake_failure异常---与众不同的原因相关推荐
- SoapUI 请求 https 报 javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
SoapUI 请求 https 报 javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 在 E:\ ...
- 使用Java访问https接口javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
jdk1.6,证书:SHA256+TLSv1.2 使用Java访问https://**************** 接口 控制台提示握手失败错误:javax.net.ssl.SSLHandsh ...
- javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
问题描述:在jdk1.7环境中使用HttpURLConnection发送https请求时,异常了 javax.net.ssl.SSLHandshakeException: Received fatal ...
- javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure问题解决
最近在生产环境调用Https接口出现这个问题javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure,经 ...
- 解决javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure报错
背景 java版本1.8.0,今天尝试用Java去访问一个https接口,但抛出下面的异常: javax.net.ssl.SSLHandshakeException: Received fatal a ...
- 搞定 javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 问题!
开始碰到这个问题找遍了各种方法,其实还是需要耐心的先搞清楚原因再想方法靠谱,这里也总结下这个异常的多种解决方案, 首先先理解下为什么出现handshake?字面理解是客户端与服务端握手失败,能导致握手 ...
- 访问https,抛出的异常javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
话说这个坑有点深,查阅大半个百度几乎没解决 部分网友解释:是因为jdk中jce的安全机制导致报的错,按照大家的方式,要去oracle官网下载对应的jce包替换jdk中的jce包. jce所在地址: % ...
- 排查https请求出现received fatal alert: internal_error的问题
目录 背景 https网络协议交互 net.debug查看信息 Apache Httpclient与 Netty的http请求 server_name 错误原因 修复方案 方案一 方案二 背景 通知某 ...
- Could not transfer artifact (https://repo.maven.apache.org/maven2): Received fatal alert: protocol_v
异常信息 Failed to read artifact descriptor for org.slf4j:slf4j-api:jar:1.7.2 org.eclipse.aether.resolut ...
最新文章
- cf1139D. Steps to One(dp)
- Docker学习笔记【一】
- Building your training into your researcing
- shell+mysql获取数据库名_shell操作mysql数据库
- 【数据结构与算法】判断单链表是否有环的算法
- etc php5 conf.d,php – nginx:[emerg]“location”指令不允许在/etc/nginx/conf.d/default.conf中使用:...
- android 线程池 怎么用,android中的线程池 怎么用
- gitolite安装及配置
- 医院后勤管理软件系统助力医院后勤管理实施国家数字低碳战略
- 自动量程万用表的实现原理_自动量程万用表模块设计方案[图]
- linux+mint+xfce开WiFi,为LinuxMint XFCE增加一键共享
- Mybatis拦截器 拦截所有更新操作
- 如何下载网页中的小视频
- 剪轴凝截Analdeta.Tessera.Pro.v3.2.2.Build.2015.10.05.Win64 1CD
- 苹果PD20W火爆方案看这里!!!
- oracle 对表重建索引,oracle 重建索引方法 分析
- 高效率完成一次接入80个手游渠道SDK——游戏接入SDK服务端篇
- 微服务之Spring Cloud Alibaba Nacos基础学习
- 微信开发工具无法支持vue文件
- c语言打出的王字图形图形,C语言编程宝典(王大刚) 3 关键字和标识符
热门文章
- 计算机系统时间无法修改,笔记本电脑系统时间无法修改该怎么处理
- Android常用学习网站
- maven项目集成findbugs详解
- 面向对象数据库(Object Oriented Databases)
- vba操作IE浏览器
- 《惢客创业日记》2021.08.10-11(周二)问了凉粉儿两个问题
- C++11 chrono 库
- 文件框上传文件选中文件后路径变成了C:\fakepath
- 第四章:搭建Windows server AD域和树域
- 家用计算机做服务器,将服务器CPU安装到家用PC上合适?_服务器_服务器产业-中关村在线...