【问题标题】:Spring Webflux WebClient - Specify the TLS version (between TLSv1.2 and TLSv1.3) used when sending outbound requestSpring Webflux WebClient - 指定发送出站请求时使用的 TLS 版本(介于 TLSv1.2 和 TLSv1.3 之间)
【发布时间】:2021-04-30 01:53:41
【问题描述】:

关于 Spring Webflux 的 Spring WebClient 的小问题,以及发送出站 http 请求时如何配置 TLS 版本(我是客户端)。

在 SpringBoot MVC 项目(不是 Webflux)中,我使用的是 Webflux Webclient(可以将两者混合使用)。

我正在使用客户端调用我完全无法控制的两个外部方 HTTP 服务器。 第一个服务是 AliceService。 Alice 服务配置为仅接受 TLSv1.2 的请求

第二个服务是 BobService。 Bob 服务配置为仅接受 TLSV1.3 的请求

因此,我目前面临一个问题。我永远无法同时给他们两个打电话。

我尝试了不同的组合

-Djdk.tls.client.protocols=TLSv1.2
-Djdk.tls.client.protocols=TLSv1.3

server.ssl.enabled-protocols=TLSv1.2
server.ssl.enabled-protocols=TLSv1.3

每次,我要么将所有出站请求更改为 TLSv1.2(因此仅接受 TLSv1.3 的服务将失败),要么将我所有的出站调用更改为 TLSv1.3(因此仅接受 TLSv1.2 的服务将失败)。

我什至有两个不同的 WebClient 实例。

请问在发送出站请求时如何配置使用哪个TLS版本? 请问这个问题怎么解决?

谢谢

【问题讨论】:

    标签: java spring-boot ssl


    【解决方案1】:

    您可以为此创建两个单独的 Web 客户端。一个用于 TLSv1.2,一个用于 TLSv1.3。

    这是您可以用来构建 WebClient 以及您需要的其他配置的最少代码 sn-p。

    用于 TLSv1.2 的 WebClient

        final SslContext sslContextForTls12 = SslContextBuilder.forClient()
                .protocols("TLSv1.2")
                .build();
        
        final HttpClient httpClientForTls12 = HttpClient.create()
                .secure(ssl -> ssl.sslContext(sslContextForTls12));
                
        final WebClient webClientForTls12 = WebClient.builder()
                .clientConnector(new ReactorClientHttpConnector(httpClientForTls12))
                .build();
    

    用于 TLSv1.3 的 WebClient

        final SslContext sslContextForTls13 = SslContextBuilder.forClient()
                .protocols("TLSv1.3")
                .build();
        
        final HttpClient httpClientForTls13 = HttpClient.create()
                .secure(ssl -> ssl.sslContext(sslContextForTls13));
                
        final WebClient webClientForTls13 = WebClient.builder()
                .clientConnector(new ReactorClientHttpConnector(httpClientForTls13))
                .build();
    

    我已经为支持各种 TLS 版本的网站测试了此配置。 This answer 提到了我用于测试的网站列表。

    【讨论】:

      【解决方案2】:

      这不应该是硬编码/配置,而是在 TLS 握手期间根据服务器和客户端的能力自动协商,否则它会成为维护的噩梦。您无需担心降级攻击,因为 TLS 具有检测保护机制。

      你应该可以看到这个:-Djavax.net.debug=all 或类似的。见JSSE Reference Guide, Debugging Utilities

      如果您想避免某些旧版本的 TLS,正确的解决方案是将不安全的旧密码列入黑名单(由于安全性/合规性),这可以通过更改配置文件中的 jdk.tls.disabledAlgorithms 来实现:jre/lib/security/java.security,在最新的 Java 安装包含相当安全的默认值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-01-30
        • 2019-10-12
        • 2020-11-18
        • 1970-01-01
        • 2019-09-19
        • 2019-08-02
        • 2021-02-24
        相关资源
        最近更新 更多