拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 如何在Apache HttpClient中设置TLS版本

如何在Apache HttpClient中设置TLS版本

白鹭 - 2021-11-24 694 0 0

1.简介

Apache HttpClient是一个低级,轻量级的客户端HTTP库,用于与HTTP服务器进行通信。在本教程中,我们将学习如何在使用HttpClient时配置支持的传输层安全性(TLS)版本。我们将首先概述客户端和服务器之间TLS版本协商的工作方式。之后,我们将研究使用HttpClient时配置受支持的TLS版本的三种不同方式

2. TLS版本协商

TLS是一种互联网协议,可在两方之间提供安全,可信任的通信。它封装了诸如HTTP之类的应用程序层协议。自从1999年首次发布以来,TLS协议已进行了多次修订。因此,对于客户端和服务器,首先要商定在建立新连接时将使用哪个版本的TLS,这一点很重要。客户端和服务器交换问候消息后,将同意TLS版本:

  1. 客户端发送支持的TLS版本的列表。
  2. 服务器选择一个,并在响应中包括所选版本。
  3. 客户端和服务器使用所选版本继续进行连接设置。

正确配置Web客户端支持的TLS版本非常重要,因为存在降级攻击的风险。请注意,为了使用最新版本的TLS(TLS 1.3),我们必须使用Java 11或更高版本。

3.静态设置TLS版本

3.1 SSLConnectionSocketFactory

让我们用HttpClientBuilder通过暴露HttpClients#custom构建器方法,以定制我们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进行通信。请注意,在4.3之前的Apache HttpClient版本中,该类称为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.example.com. SSLSocket之前插入自定义逻辑的功能,我们的应用程序现在可以自定义TLS通信详细信息。

5.结论

在本文中,我们研究了使用Apache HttpClient库时配置受支持的TLS版本的三种不同方式。我们已经了解了如何为所有连接或基于每个连接设置TLS版本。

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *