Java1.7.0_80配置HttpClient4.5.13 TLSv1.2握手报close_notify异常怎么解决
Java 1.7.0_80环境下HttpClient 4.5.13兼容TLSv1.2方案
根因说明
Java 1.7.0_80默认禁用TLSv1.1、TLSv1.2协议,且默认加密策略不支持高强度加密套件;现有代码仅指定了SSLContext的协议版本,未覆盖HttpClient默认的协议版本参数,导致握手过程中协议 fallback 触发服务端主动关闭连接。
修复步骤
步骤1:调整JRE配置,开启TLSv1.2支持
- 打开JRE安装目录下
jre/lib/security/java.security文件,找到jdk.tls.disabledAlgorithms配置项,删除配置中的TLSv1.1、TLSv1.2,解除协议禁用。 - 安装Java 7对应的JCE无限制强度管辖策略包:下载对应版本的JCE包后,替换
jre/lib/security目录下的local_policy.jar和US_export_policy.jar文件,解决日志中256位加密套件不可用的问题。
步骤2:修改业务代码,覆盖默认协议版本参数
修改后的配置代码如下,核心是显式指定HttpClient协议版本、自定义SSL套接字强制启用TLSv1.2,直接覆盖protocolversion.Default默认值:
// 全局JVM参数覆盖默认协议配置 System.setProperty("https.protocols", "TLSv1.2"); System.setProperty("jdk.tls.client.protocols", "TLSv1.2"); // 初始化TLSv1.2专用SSLContext SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); sslContext.init(null, null, null); SSLContext.setDefault(sslContext); // 自定义SSL连接套接字工厂,强制每个连接的套接字仅使用TLSv1.2 SSLConnectionSocketFactory f = new SSLConnectionSocketFactory(sslContext, new String[]{"TLSv1.2"}, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER) { @Override public Socket createSocket(HttpContext context) throws IOException { Socket socket = super.createSocket(context); if (socket instanceof SSLSocket) { ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.2"}); } return socket; } }; // 构建HttpClient时显式指定HTTP协议版本,覆盖protocolversion.Default默认值 this.httpclient = HttpClients.custom() .setSSLSocketFactory(f) .setVersion(HttpVersion.HTTP_1_1) .build(); // 后续请求执行逻辑不变 HttpPost httpmethod = new HttpPost(url); if (this.httpclient != null) { ResponseHandler<String> responseHandler = new BasicResponseHandler(); String responseBody = httpclient.execute(httpmethod, responseHandler); }
步骤3:验证生效
如果仍有异常,可添加JVM启动参数-Djavax.net.debug=ssl,handshake打印完整SSL握手日志,确认ClientHello阶段的协议版本为TLSv1.2,且客户端提交的加密套件和服务端支持的套件匹配。
内容的提问来源于stack exchange,提问作者Sumit Thakur
相关产品推荐
相关产品推荐

