Веб — клиент Spring Webflux-Укажите версию TLS (между TLSv1.2 и TLSv1.3), используемую при отправке исходящего запроса

#java #spring-boot #ssl

Вопрос:

Небольшой вопрос, касающийся веб-клиента Spring от Spring Webflux, и как настроить версии TLS при отправке исходящего http-запроса (где я являюсь клиентом).

В проекте SpringBoot MVC (не Webflux) я использую Webflux Webclient (который можно смешивать).

Я использую клиент для вызова двух сторонних HTTP-серверов, которые я абсолютно не контролирую. Первая услуга-это AliceService. Служба Alice настроена на прием только запросов, которые являются TLSv1.2

Вторая услуга-это бобслейная служба. Служба 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 используется при отправке исходящего запроса? Как решить эту проблему, пожалуйста?

Спасибо

Ответ №1:

Для этой цели вы можете создать два отдельных веб-клиента. Один для TLSv1.2 и один для TLSv1.3.

Вот минимальный фрагмент кода, который вы можете использовать для создания своего веб-клиента вместе с другой необходимой вам конфигурацией.

Веб-клиент для TLSv1.2

     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

     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.
В этом ответе упоминается список сайтов, которые я использовал для тестирования.

Ответ №2:

Это не должно быть жестко закодировано/настроено, но автоматически согласовано во время TLS-квитирования, в зависимости от возможностей сервера и клиента, в противном случае это становится кошмаром обслуживания. Вам не нужно беспокоиться об атаках с понижением рейтинга, так как TLS имеет механизм защиты для их обнаружения.

Вы должны быть в состоянии увидеть это с помощью: -Djavax.net.debug=all или аналогичного. См. Справочное руководство JSSE, Утилиты отладки

Если вы хотите избежать некоторых более старых версий TLS , правильным решением является внесение в черный список небезопасных старых шифров (из-за безопасности/соответствия требованиям), что может быть достигнуто путем изменения: jdk.tls.disabledAlgorithms в файле конфигурации: jre/lib/security/java.security , который в современных установках Java содержит достаточно безопасные значения по умолчанию.