安全上

我刚刚宣布了新消息学习Spring Security课程,包括Spring Security 5中新的OAuth2堆栈的完整材料:

>>查看课程

1.介绍

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

2.TLS版本协商

TLS是一种互联网协议,在双方之间提供安全、可信的通信。它封装了像HTTP这样的应用层协议。自1999年首次发布以来,TLS协议已经修订了好几次。因此,客户端和服务器在建立新连接时首先就使用哪个版本的TLS达成一致是很重要的。TLS版本在客户端和服务器交换hello消息后达成一致:

  1. 客户端发送支持的TLS版本列表。
  2. 服务器选择一个并在响应中包含所选的版本。
  3. 客户端和服务器使用选定的版本继续建立连接。

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

3.静态设置TLS版本

3.1。SSLConnectionSocketFactory

让我们使用HttpClientBuilder公开的httpclient #定制生成器方法来定制我们的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配置支持的TLS版本https.protocols系统属性。此方法防止将值硬编码到应用程序代码中。相反,我们将配置HttpClient设置连接时使用系统属性。HttpClient API提供了两种方法来实现这一点。第一种是viahttpclient # 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(sslcontext . createdefault ()){@Override protected void prepareSocket(SSLSocket socket) {String hostname = socket. getinetaddress ().getHostName();如果(hostname.endsWith(“internal.system.com”)){插座。setEnabledProtocols(new String[] {"TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"});} else{套接字。setEnabledProtocols(新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版本。本文中使用的代码示例是可用的在GitHub

安全底

我刚刚宣布了新消息学习Spring Security课程,包括Spring Security 5中新的OAuth2堆栈的完整材料:

>>查看课程
本文评论关闭!