1, the introduction of

Apache HttpClient is a low-level, lightweight client-side HTTP library for communicating with HTTP servers. In this tutorial, we will learn how to configure the supported Transport Layer Security (TLS) version when using HttpClient. We’ll start with an overview of how TLS version negotiation works between client and server. After that, we’ll look at three different ways to configure the supported version of TLS when using HttpClient.

2. TLS version negotiation

TLS is an Internet protocol that provides secure, trusted communication between two parties. It encapsulates application layer protocols like HTTP. The TLS protocol has been revised several times since it was first published in 1999. Therefore, it is important that the client and server first agree on the version of TLS they will use when establishing a new connection. The TLS version is agreed upon after the client and server exchange hello messages:

  1. The client sends a list of supported TLS versions.
  2. The server selects one and includes the selected version in the response.
  3. The client and server continue the connection Settings with the selected version.

Because of the risk of a de-escalation attack, it is important to correctly configure the version of TLS supported by the Web client. Please note that in order to use the latest version of TLS (TLS 1.3), we must use Java 11 or higher.

3. TLS version is fixed

3.1, SSLConnectionSocketFactory

Let’s customize our HttpClient configuration using the HttpClientBuilder provided with the HttpClients# Custom build method. The builder pattern allows us to our own SSLConnectionSocketFactory, it will be based on a set of the required support TLS version instantiated:

SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( SSLContexts.createDefault(), New String [] {" TLSv1.2 ", "TLSv1.3}", null, SSLConnectionSocketFactory. GetDefaultHostnameVerifier ()); CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();

The returned HttpClient object is now ready to perform HTTP requests. By explicitly set in the SSLConnectionSocketFactory constructor support agreement, the client will only support by TLS 1.2 or 1.3 TLS communication. Note that in versions prior to Apache HttpClient 4.3, this class was called SSLSocketFactory.

3.2. Java runtime parameters

Alternatively, we can configure the supported version of TLS using the Java https.protocols system property. This approach prevents the value from having to be hard-coded into the application code. Instead, we will configure HttpClient to use this system property when setting up the connection. The HttpClient API provides two ways to do this. The first is via HttpClients#createSystem:

CloseableHttpClient httpClient = HttpClients.createSystem();

If more client configuration is required, we can use the Builder method instead:

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

Both methods tell HttpClient to use system properties during connection configuration. This allows us to set the desired version of TLS using command-line arguments while the application is running. Such as:

$java-dHTTPs.protocols =TLSv1.1,TLSv1.2, tlsv1.3-jar webclient.jar

4. Set the TLS version dynamically

You can also set the TLS version based on connection details such as hostname and port. We will extend SSLConnectionSocketFactory and override prepareSocket method. The client calls the prepareSocket method before starting a new connection, which will allow us to decide which TLS protocol to use on a per-connection basis. Support for older TLS versions can also be enabled, but only if the remote host has a specific subdomain:

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();

In the above example, the PrepreparesSocket method first gets the remote host name to which the SSLSocket will connect, and then uses the host name to determine the TLS protocol to enable. Now, our HTTP client will enforce TLS 1.3 on every request, except that the target hostname is formatted as *.internal.system.com. With the ability to insert custom logic before creating a new SSLSocket, our application can now customize the details of TLS communication.

5, conclusion

In this article, we looked at three different ways to configure the supported version of TLS when using the Apache HttpClient library. We have seen how to set the TLS version for all connections or on a per-connection basis.

Original: https://www.baeldung.com/apac…

Code farmers panda

For more technical products, please visit my personal website https://pinmost.com, or pay attention to the public account [Code Panda].