解决jdk1.7 不支持TLS1.2的问题

本文介绍了解决因JDK默认SSL协议与服务器配置不兼容导致的连接失败问题。通过调整代码以支持多种SSL协议,实现了与服务器的成功连接。同时,详细解释了不同JDK版本对SSL协议的支持情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个问题是在生产环境调整之后出现的,因为之前是好使的,后来又一天突然不好使了,观察日志发现代码抛异常,感觉是没有连接上服务器,但是其他环境是好使的,有点疑惑,分析后发现可能是ssl的协议问题,所以观察了下Nginx的配置,发现运维伙伴基于公司的安全机制,将ssl_protocols从 TLSv1.2 TLSv1.1 TLSv1.0; 调整成了TLSv1.2 TLSv1.1; 然后查了下资料,发现jdk的各个版本对ssl协议的默认支持是不一样的,代码里面写的是:

SSLContext sslContext = SSLContext.getInstance("SSL","SunJSSE"); 

这个说白了用的是当前JDK版本的默认协议,我当前用的是JDK1.7所以JDK1.7默认使用的是TLSv1.0,虽然JDK1.7也支持TLSv1.2 TLSv1.1但是默认使用的并不是这两个,因此我这边调整了下代码,用三种协议挨个去连接,谁链接成功就用谁,代码如下:

if (buildHttpsConn(map, "TLSv1") || buildHttpsConn(map, "TLSv1.1")|| buildHttpsConn(map, "TLSv1.2")) {
	            		
	            		// 获取封装在map中的链接对象
	            		httpsConn = (HttpsURLConnection) map.get("httpsConn");
	            		
	            		// 取得该连接的输入流,以读取响应内容
		                insr = new InputStreamReader(httpsConn.getInputStream());
		                
		                // 读取服务器的响应内容并显示
		                int respInt;
		                respInt = insr.read();
		                while (respInt != -1){
		                    sb.append((char) respInt);
		                    respInt = insr.read();
		                }
		                data = sb.toString();
					}



/**
	 * 获取httpsConn链接
	 * @param map (url,httpsConn)
	 * @param protocol 协议
	 * @return
	 */
	private boolean buildHttpsConn(Map<String, Object> map, String protocol){
		
		try {
			URL url = (URL) map.get("url");
			
			//创建SSLContext对象,并使用我们指定的信任管理器初始化
	        TrustManager[] tm = {new MyX509TrustManager ()}; 
	        SSLContext sslContext = SSLContext.getInstance(protocol); 
	        sslContext.init(null, tm, new java.security.SecureRandom()); 

	        //从上述SSLContext对象中得到SSLSocketFactory对象
	        SSLSocketFactory ssf = sslContext.getSocketFactory();

	        // 创建HttpsURLConnection对象,并设置其SSLSocketFactory对象
	        HttpsURLConnection httpsConn = (HttpsURLConnection) url.openConnection();
	        
	        //创建HttpsURLConnection对象,并设置其SSLSocketFactory对象
	        httpsConn.setSSLSocketFactory(ssf);
	        
	        LOGGER.info("开始建立https链接使用{}协议", protocol);
	        httpsConn.getResponseCode();
	        map.put("httpsConn", httpsConn);
		} catch (Exception e) {
			LOGGER.error("建立https链接使用{}协议无效!", protocol);
			return false;
		}
		return true;
	}

问题得到了解决,下面介绍一下JDK各个版本默认支持的协议,以及他本身支持哪些协议。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浮生(FS)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值