原文:https://blog.csdn.net/gudejundd/article/details/89640741

1.什么是TLS
SSL 是“Secure Sockets Layer”的缩写,中文叫做“安全套接层”。它是在上世纪90年代中期,由网景公司设计的。(顺便插一句,网景公司不光发明了 SSL,还发明了很多 Web 的基础设施——比如“CSS 样式表”和“JS 脚本”)
为啥要发明 SSL 这个协议捏?因为原先互联网上使用的 HTTP 协议是明文的,存在很多缺点——比如传输内容会被偷窥(嗅探)和篡改。发明 SSL 协议,就是为了解决这些问题。
到了1999年,SSL 因为应用广泛,已经成为互联网上的事实标准。IETF 就在那年把 SSL 标准化。标准化之后的名称改为 TLS(是“Transport Layer Security”的缩写),中文叫做“传输层安全协议”。
很多相关的文章都把这两者并列称呼(SSL/TLS),因为这两者可以视作同一个东西的不同阶段。

2.TLS有哪些版本、JDK默认支持哪些版本
TLS版本有: SSLv2、 SSLv3、 TLSv1、 TLSv1.1、 TLSv1.2
其中 SSLv2、SSLv3应该没有在用的,一些公司都已经禁用
TLSv1、TLSv1.1 目前还有公司在用,不过很过公司开始陆续禁用。

JDK支持的tls版本:

在这里插入图片描述
3.java程序中如何指定TLS版本?
目前从JDK1.8开始都默认TLSv1.2协议了,但对于还在用版本低的JDK时,如果服务端禁用了TLSv.1 ,而代码中没有指定具体协议版本,那么JDK都是采用默认版本建立连接。这样会出现以下错误:
javax.net.ssl.SSLException: Received fatal alert: protocol_version)
出现此类错误,有可能就是服务端和客户端协议版本不一致导致的。
程序中可以这样解决:

第一种方式:(SF代碼不全不好用)

			//以下只贴了如何设置tls版本号的代码
SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); //这边指定tls版本
sslContext.init(kmf.getKeyManagers(),tm, null);
SSLSocketFactory factory = sslContext.getSocketFactory();
URL url = new URL(merchantInfo.getUrl());
HttpsURLConnection urlc = (HttpsURLConnection) url.openConnection();
urlc.setSSLSocketFactory(factory); //这一步很重要

采用httpClient发送请求也和这个代码类似,就不放示例了

第二种方式:(SF好用,直接加到client create前就行)

			SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null,null,null);
SSLContext.setDefault(sslContext);

第二种方式setDefault是全局性的,相当于整个程序如果没有指定TLS版本,那么默认都采用1.2,会影响程序中其它使用默认TLS版本的地方,比如:之前使用默认TLSv1.0版本的,如果你设置了setDefault()变成1.2了,如果服务端不支持1.2协议会发生异常,不过现在应该没有不支持1.2协议的,所以大家自己考虑采用哪种方式。
还有人说用了第二种方式不起作用,那么我解释一下:
比如使用JDK自带的HttpsURLConnection发送https请求,代码如下:(sf不知道怎麽用,沒試過)

			//以下只是部分需要展示的代码
URLConnection connection = url.openConnection(); //这一步回去创建连接,这时候会调用SSLContext.getDefault().getSocketFactory(); 会返回我们上面设置的TLSv1.2协议SSLSocketFactory,这样我们setDefault()方法是有效的。
HttpsURLConnection httpsURLConnection = (HttpsURLConnection) connection;
httpsURLConnection.setRequestMethod(HttpTransportConstants.METHOD_POST);
httpsURLConnection.setUseCaches(false);
httpsURLConnection.setDoInput(true);
httpsURLConnection.setDoOutput(true);
httpsURLConnection.setConnectTimeout(getConnectTimeout());
httpsURLConnection.setReadTimeout(getReadTimeout());*/
//不过有些程序会有如下代码,SSLSocketFactory又重新设置了一遍, SSLContext.getInstance("ssl");获取的是TLSv1.0协议,这样又使用了TLS1.0协议进行通讯了,就不会起到效果,其实下面这点代码就是第一种方式介绍的。
SSLContext sc = SSLContext.getInstance("ssl");
sc.init(null, null, new java.security.SecureRandom());
httpsURLConnection.setSSLSocketFactory(sc.getSocketFactory());

原文2:https://blog.csdn.net/bbc2005/article/details/80890829

解决办法

1:把JDK升级到1.8。由于该网站使用的是TLSv1.2协议,JDK1.8默认是该协议,故把客户端JDK升级到1.8可以解决该问题。

2:在JDK1.7客户端代码中指定使用的协议System.setProperty("https.protocols", "TLSv1.2") →(SF親測好用)

System.setProperty("jdk.tls.client.protocols", "TLSv1.2") →(SF親測不好用)。注意,该方法有时候会莫名的失效,原因未知。

3:在VM参数中设置-Dhttps.protocols=TLSv1.2或-Djdk.tls.client.protocols=TLSv1.2。注意,该方法有时候会莫名的失效,原因未知。(sf未測試,不會用)

4:使用第三方库了,参考http://ligaosong.iteye.com/blog/2356346

5:使用httpclient,其支持配置使用指定协议

原文3:https://blog.csdn.net/Blade_/article/details/97491193

因面临Oracle旗下NetSuite云ERP密码套件的升级(安全传输层协议由之前的TLS v1.1升级到TLS v1.2),导致我司WMS与ERP系统接口无法正常使用,具体报错如下:

后经查阅资料,发现jdk1.7是默认采用的TLS v1.1和TLSv1.0版本的,因此只需采用如下操作即可解决:(SF:和上面好用的“第二種方法”其實本質相同,多了Try catch更好了)

try {
SSLContext ctx = SSLContext.getInstance("TLSv1.2");
ctx.init(null, null, null);
SSLContext.setDefault(ctx); //将你所要使用的TLS版本设为默认
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
System.setProperty("https.protocols", "TLSv1.2");

原文4:java.lang.ClassNotFoundException: com.ibm.websphere.ssl.protocol.SSLSocketFactory的解决办法

Websphere8.5 + IBM JDK 下访问HTTPS/SSL 出现java.lang.ClassNotFoundException: com.ibm.websphere.ssl.protocol.SSLSocketFactory的解决办法

第一种方法:在程序初始化的时候加入以下代码:

      //solve the error: java.lang.ClassNotFoundException: com.ibm.websphere.ssl.protocol.SSLSocketFactory
Security.setProperty("ssl.SocketFactory.provider", "");
Security.setProperty("ssl.ServerSocketFactory.provider", "");

(SF,這個ClassNotFoundException的錯誤最初是沒有的,當我爲了測試TLS1.2把RAD的jdk從1.6變成1.7,又變回1.6后出現了,然後就必須加上面這段代碼才好用)


根据Oracle文档知各版本JDK默认使用的TLS协议如下:

https://blogs.oracle.com/java-platform-group/diagnosing-tls,-ssl,-and-https


2019年11月18日 使用apache解決這個問題:

參考:

1,官方sample代碼:

https://hc.apache.org/httpcomponents-client-4.5.x/examples.html

2,jar包下載地址(官方)

http://hc.apache.org/downloads.cgi

SO2O連接報錯javax.net.ssl.SSLException: Received fatal alert: protocol_version)的更多相关文章

  1. JAVA连接MySQ报错:Caused by: javax.net.ssl.SSLException: Received fatal alert: protocol_version

    Caused by: javax.net.ssl.SSLException: Received fatal alert: protocol_version at sun.security.ssl.Al ...

  2. jdk1.7访问https报javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure问题解决

    本地jdk版本java version "1.8.0_31",代码中已对https做了相应处理:信任所有来源证书,运行正常:上包到服务器(服务器jdk版本java version ...

  3. 转:javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 解决方案

    转:javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 解决方案javax.net.ssl.SSL ...

  4. 处理Https 异常记录 javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

    http://blog.csdn.net/baidu_18607183/article/details/51595330 https://blogs.oracle.com/java-platform- ...

  5. javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

    SSL握手失败:用JDK1.8做发邮件的功能遇到这种问题处理方式是:将目录 %JAVA_HOME%\...\jre\lib\security里的local_policy.jar,US_export_p ...

  6. javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 解决方案

    这个是jdk导致的,jdk里面有一个jce的包,安全性机制导致的访问https会报错,官网上有替代的jar包,换掉就好了 目录 %JAVA_HOME%\jre\lib\security里的local_ ...

  7. SoapUI 请求 https 报 javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

    在 E:\ProgramFiles\SmartBear\SoapUI-Pro-5.1.2\bin\SoapUI-Pro-5.1.2.vmoptions 中添加一行代码,代码如下: -Dsoapui.h ...

  8. SSL异常javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

    jdk 7 http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html jdk 8 http: ...

  9. javax.net.ssl.SSLException: java.lang.UnsupportedOperationException

    Loading KeyStore C:\Tool\jdk1.7.0_71\jre\lib\security\jssecacerts... Opening connection to www.googl ...

随机推荐

  1. Go part 2 基础语法

    关键字.标识符 标识符: 是用户或系统定义的有意义单词组合,或单词与数字组合(具体意义有定义者决定) 标识符以字母下划线开头,大小写敏感,比如:boy,  Boy,  _boy,  _(匿名变量,用来 ...

  2. HashSet和CopyOnWriteArraySet(转载)

    前言 这篇文章的目的如下: HashSet是如何保证元素的不重复和无序 HashSet的增删(改查?)原理 CopyOnWriteArraySet支持并发的原理 CopyOnWriteArraySet ...

  3. 用pythoninstall cefpython打包exe,制作自己的浏览器

    cefpython浏览器 介绍 用pythoninstall cefpython打包exe,制作自己的浏览器, 软件架构 PyInstaller: 3.4 Python: 3.5.4 Platform ...

  4. Ajax长连接和SignalR(刷新客户端数据)的区别

    ajax实现长连接   <%@ page language="java" import="java.util.*" pageEncoding=" ...

  5. idou老师教你学Istio :5分钟简析Istio异常检测

    异常检测 异常检测和踢出异常主机是一个动态检查上游主机是否正常工作,对不健康主机进行移除的过程.异常检测是一种被动健康检查,根据返回状态码来判断是否满足移除条件,最后将主机移除,首先我们来了解下驱逐算 ...

  6. js 获取扫码枪信息

    ---- js 获取扫码枪不需要记录 lastCode 啊,只需要在时间超出范围的时候重置 lastTime 和 code 就行了.如果 码枪会输入回车,那就在 keyCode === 13 的时候使 ...

  7. JAVA遇见HTML——JSP篇(JSP指令与动作元素)

  8. Enum 类型

    枚举类型(Enumerated Type) 什么是枚举? 枚举是一个被命名的整型常数的集合.在多种编程语言中都有使用(C/C++/c#/java等). 示例 public enum Size { S, ...

  9. CodeForces 840A - Leha and Function | Codeforces Round #429 (Div. 1)

    /* CodeForces 840A - Leha and Function [ 贪心 ] | Codeforces Round #429 (Div. 1) A越大,B越小,越好 */ #includ ...

  10. [Luogu P4145] 上帝造题的七分钟2 / 花神游历各国

    题目链接 题目简要:我们需要一个能支持区间内每一个数开方以及区间求和的数据结构. 解题思路:说道区间修改区间查询,第一个想到的当然就是分块线段树.数据范围要用long long.本来我是看到区间这两个 ...