乐趣区

关于java:如何在Apache-HttpClient中设置TLS版本

1、简介

Apache HttpClient 是一个底层、轻量级的客户端 HTTP 库,用于与 HTTP 服务器进行通信。
在本教程中,咱们将学习如何在应用 HttpClient 时配置反对的传输层平安(TLS)版本。
咱们将首先概述 TLS 版本协商如何在客户端和服务器之间工作。
之后,咱们将看看在 应用 HttpClient 时配置反对的 TLS 版本的三种不同形式

2、TLS 版本协商

TLS 是一种互联网协议,可在两方之间提供平安、可信的通信。它封装了像 HTTP 这样的应用层协定。
TLS 协定自 1999 年首次公布以来已屡次订正。
因而,客户端和服务器在建设新连贯时,首先就他们将应用的 TLS 版本达成统一十分重要。
TLS 版本在客户端和服务器替换 hello 音讯后达成统一:

  1. 客户端发送反对的 TLS 版本列表。
  2. 服务器抉择一个并在响应中蕴含所选版本。
  3. 客户端和服务器应用所选版本持续连贯设置。

因为存在降级攻打的危险,因而正确配置 Web 客户端反对的 TLS 版本十分重要。
请留神,为了应用最新版本的 TLS(TLS 1.3),咱们必须应用 Java 11 或更高版本

3、固定设置 TLS 版本

3.1、SSLConnectionSocketFactory

让咱们通过 HttpClients#custom 定制构建办法提供的 HttpClientBuilder,来定制咱们的HTTPClient 配置。
此构建器模式容许咱们传入咱们本人的SSLConnectionSocketFactory,它将依据一组所需反对的 TLS 版本进行实例化:

SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(SSLContexts.createDefault(),
  new String[] { "TLSv1.2", "TLSv1.3"},
  null,
  SSLConnectionSocketFactory.getDefaultHostnameVerifier());

CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();

返回的 Httpclient 对象当初能够执行 HTTP 申请了。
通过在 SSLConnectionSocketFactory 构造函数中显式设置反对的协定,客户端将仅反对通过 TLS 1.2 或 TLS 1.3 的通信。
请留神,在 Apache HttpClient 4.3 之前的版本中,该类称为SSLSocketFactory

3.2、Java 运行时参数

另外,咱们能够应用 Java 的 https.protocols 零碎属性配置反对的 TLS 版本。
此办法能够避免必须将值硬编码到利用程序代码中。
相同,咱们将配置 HttpClient 以在设置连贯时应用该零碎属性。
HttpClient API 提供了两种办法来实现。第一个是通过HttpClients#createSystem

CloseableHttpClient httpClient = HttpClients.createSystem();

如果须要更多的客户端配置,咱们能够应用 builder 办法代替:

CloseableHttpClient httpClient = HttpClients.custom().useSystemProperties().build();

这两种办法都通知 HttpClient 在连贯配置期间应用零碎属性。
这容许咱们在利用程序运行时应用命令行参数设置所需的 TLS 版本。例如:

$ java -Dhttps.protocols=TLSv1.1,TLSv1.2,TLSv1.3 -jar webClient.jar

4、动静设置 TLS 版本

还能够依据主机名和端口等连贯详细信息设置 TLS 版本。咱们将扩大 SSLConnectionSocketFactory 并笼罩 prepareSocket 办法。
客户端会在启动新连贯之前调用 prepareSocket 办法,这将能够让咱们在每个连贯的根底上决定应用哪些 TLS 协定。
也能够启用对旧 TLS 版本的反对,但前提是近程主机具备特定的子域:

SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(SSLContexts.createDefault()){

    @Override
    protected void prepareSocket(SSLSocket socket) {String hostname = socket.getInetAddress().getHostName();
        if (hostname.endsWith("internal.system.com")){socket.setEnabledProtocols(new String[] {"TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"});
        }
        else {socket.setEnabledProtocols(new String[] {"TLSv1.3"});
        }
    }
};
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();

在下面的示例中,prepareSocket办法首先获取 SSLSocket 将连贯到的近程主机名,而后应用主机名来确定要启用的 TLS 协定。
当初,咱们的 HTTP 客户端将对每个申请强制执行 TLS 1.3,除了指标主机名的格局为 *.internal.system.com
因为可能在创立新 SSLSocket 之前插入自定义逻辑,咱们的应用程序当初能够自定义 TLS 通信的详细信息。

5、论断

在本文中,咱们钻研了在应用 Apache HttpClient 库时配置反对的 TLS 版本的三种不同形式。
咱们曾经理解了如何为所有连贯或基于每个连贯设置 TLS 版本。

原文:https://www.baeldung.com/apac…

翻译:码农熊猫

更多技术干货,请拜访我的集体网站 https://pinmost.com,或关注公众号【码农熊猫】

退出移动版