当前位置: 首页 > news >正文

升级 JDK 17 碰到的请求 https 问题

问题

升级 JDK 17 后,一个自定义请求,提示 The server selected protocol version TLS10 is not accepted的异常,这个问题,在之前应该是碰到过的,所以有记录了对应的链接,https://cloud.tencent.com/developer/article/2127522。但这次在客户那部署,虽然调整了对应的参数,但依然还是请求失败。趁着周末重新验证了这个 TLSv1 的请求。

在这里插入图片描述

处理

解封 TLSv1

因为 TLSv1,TLSv1.1 有已知的安全漏洞,所以在高版本的 JDK里面默认的禁用了 TLSv1,TLSv1.1 的安全算法。通过whereis 和 ll 等命令可以定位 JAVA_HOME 目录(也可以直接尝试 echo JAVAHOME看看是否有配置对应的目录),接着定位到‘JAVA_HOME 看看是否有配置对应的目录),接着定位到`JAVAHOME看看是否有配置对应的目录),接着定位到JAVA_HOME/conf/security/java.security` 文件。

找到 jdk.tls.disabledAlgorithms部分,旧内容如下:(不同JDK 版本可能略有不同)

jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL

去除 TLSv1, TLSv1.1, ,修改如下:

jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, \DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL

如果不想修改这个配置,也可以尝试的程序运行时指定参数。

java -Djdk.tls.client.protocols="TLSv1,TLSv1.1,TLSv1.2,TLSv1.3" -Djdk.tls.server.protocols="TLSv1,TLSv1.1,TLSv1.2,TLSv1.3" -jar app.jar

通常情况下,此时应该能正常使用,但发到现场后发现还是上面的错误。

模拟环境

从提示中我们可以看到,应该是对方的https 服务使用的是 TLSv1 版本的协议,于是修改自己的 nginx 服务强制指定ssl_protocols 为 TLSv1;

        ssl_protocols TLSv1;ssl_ciphers  HIGH:!aNULL:!MD5;

此时浏览器范围页面也是异常的。

在这里插入图片描述

此时通过程序测试,提示的异常虽然有些不同,但基本可以看出是同一个问题引起的了。

在这里插入图片描述

尝试切换 hutool 的 httputil

切换 httputil 后发现服务请求自定义证书,提示下面的错误。

在这里插入图片描述

经过一番查看源代码后,发现 hutool 支持设置一个全局参数HttpGlobalConfig.setTrustAnyHost(true),设置了全局参数之后发现,请求正常了。

在这里插入图片描述

为什么 httputils 不行呢?

一开始以为是创建的 SSLContext 不同,更换成 hutool 工具创建的 SSLContext SSLContextUtil.createTrustAnySSLContext 依然还是不行。于是对比了下 hutool 和 solon 的是请求默认的类库不同,hutool 默认使用的是httpclient4,solon默认使用的是okhttp。当把 hutool 的默认请求切换到 okhttp 时,虽然一样也设置了*setTrustAnyHost*(true),但请求一样是报错的。

接着跟踪到 hutool 中 httpclient4 里面的一个关键设置。

private static SSLConnectionSocketFactory buildSocketFactory(SSLInfo sslInfo) {return null == sslInfo ? SSLConnectionSocketFactory.getSocketFactory() : new SSLConnectionSocketFactory(sslInfo.getSslContext(), sslInfo.getProtocols(), (String[])null, sslInfo.getHostnameVerifier());
}

此时可以比较明确的确定是连接客户也需要设置的问题,于是找到 OkHttpClient 创建的位置,增加设置connectionSpecs

在这里插入图片描述

solon 作者说按上述设置会导致 http 无法访问,同时还发现 okhttp 还提供了一些常量,换成如下写法兼容性更好。

connectionSpecs(Arrays.asList(ConnectionSpec.COMPATIBLE_TLS, ConnectionSpec.CLEARTEXT))

临时处理

扩展 OkHttpUtilsFactory
public class OkHttpUtilsFactoryExt extends OkHttpUtilsFactory {static final Logger log = LoggerFactory.getLogger(OkHttpUtilsFactory.class);private static final OkHttpUtilsFactory instance = new OkHttpUtilsFactory();private static final OkHttpDispatcher dispatcher = new OkHttpDispatcher();private final OkHttpClient defaultClient = createHttpClient(null, null);private static OkHttpClient createHttpClient(Proxy proxy, HttpSslSupplier sslProvider) {if (sslProvider == null) {sslProvider = HttpSslSupplierDefault.getInstance();}OkHttpClient.Builder builder =(new OkHttpClient.Builder()).connectTimeout(10L, TimeUnit.SECONDS).writeTimeout(60L, TimeUnit.SECONDS).readTimeout(60L, TimeUnit.SECONDS).dispatcher(dispatcher.getDispatcher()).addInterceptor(OkHttpInterceptor.instance).sslSocketFactory(sslProvider.getSocketFactory(), sslProvider.getX509TrustManager()).connectionSpecs(Arrays.asList(ConnectionSpec.COMPATIBLE_TLS, ConnectionSpec.CLEARTEXT)).hostnameVerifier(sslProvider.getHostnameVerifier());if (proxy != null) {builder.proxy(proxy);}return builder.build();}@Overrideprotected OkHttpClient getClient(Proxy proxy, HttpSslSupplier sslProvider) {return createHttpClient(proxy, sslProvider);}
}
扩展 HttpSslSupplier
@Component
public class ExtensionHttp extends HttpSslSupplierDefaultimplements HttpExtension, HttpSslSupplier {// for HttpSslSupplierprivate SSLContext sslContext;private String[] protocols;// for HttpExtension@Overridepublic void onInit(HttpUtils httpUtils, String url) {httpUtils.ssl(this);}@Overridepublic SSLContext getSslContext() {return SSLContextUtil.createTrustAnySSLContext();}
}
使用

如果指定了 HttpExtension的扩展为 Component,默认情况是会自动注册扩展的,测试时可能需要自己通过addExtension 的方式添加扩展。

HttpConfiguration.setFactory(new OkHttpUtilsFactoryExt());
HttpConfiguration.addExtension(new ExtensionHttp());

正式处理

等待 solon 3.5.0 版本的发布,之后切换 SSLContextUtil.createTrustAnySSLContext(),替换默认的SSLContext。

http://www.dtcms.com/a/324436.html

相关文章:

  • 从0开始的中后台管理系统-5(userList页面功能实现)
  • 自测电脑有没有木马
  • 深度学习周报(8.4~8.10)
  • 使用binutils工具解析目标文件符号表(叁)
  • Datawhale AI夏令营 多模态RAG环境问题
  • 海关 瑞数 失信企业 逆向 分析 后缀 rs
  • es查询小结
  • CSS优先级、HTTP响应状态码
  • BGP综合大实验
  • 人工智能-python-机器学习-模型选择与调优实战指南:从交叉验证到朴素贝叶斯分类
  • 为wordpress顶部header.php文件中调用不同的标题和摘要
  • 学习中的杂项知识
  • 在Word和WPS文字一页中实现一栏与多栏混排
  • 打靶日常-upload-labs(21关)
  • MyBatisPlus插件原理
  • Java 虚拟机运行时数据区组成详解
  • 【Vue2与Vue3的核心区别】响应式、运行时、编译器
  • 医学统计(随机对照研究分类变量结局数据的统计策略2)
  • 五种 IO 模型与阻塞 IO
  • Redis一站式指南二:主从模式高效解决分布式系统“单点问题”
  • 对话式BI有什么用?不懂技术也能用对话式BI搞定业务报表
  • 面对信号在时频平面打结,VNCMD分割算法深度解密
  • AMS1117-3.3 低压差线性稳压器 (LDO) 3.3V芯片 引脚图中文资料
  • 【Python 工具人快餐 · 第 4 份】
  • 【LLM】什么是Function Calling以及实现原理
  • Day41--动态规划--121. 买卖股票的最佳时机,122. 买卖股票的最佳时机 II,123. 买卖股票的最佳时机 III
  • 工业相机选择规则
  • 如何将PDF文档进行高效编辑处理!
  • Rust 实战四 | Traui2+Vue3+Rspack 开发桌面应用:通配符掩码计算器
  • Virtio 驱动初始化数据收发流程详解