1, the introduction of

Apache HttpClient is a low-level, lightweight client HTTP library for communicating with HTTP servers. In this tutorial, we’ll 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 TLS version 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 such as HTTP. The TLS protocol has been revised several times since it was first published in 1999. Therefore, it is important that clients and servers 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 using the selected version.

Because of the risk of degraded attacks, it is important to correctly configure the TLS version supported by Web clients. Please note that in order to use the latest version of TLS (TLS 1.3), we must use Java 11 or later.

3. Set the TLS version

3.1, SSLConnectionSocketFactory

Let’s customize our HTTPClient configuration using the HttpClientBuilder provided by the HttpClients#custom 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();
Copy the code

The returned Httpclient object can now 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 TLS version using Java’s HTTPS. Protocols system property. This approach prevents values from having to be hard-coded into 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();
Copy the code

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

CloseableHttpClient httpClient = HttpClients.custom().useSystemProperties().build();
Copy the code

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

$Java - Dhttps. Separate protocols = TLSv1.1 TLSv1.2, TLSv1.3 - jar webClient. Jar
Copy the code

4. Dynamically set the TLS version

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 protocols 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();Copy the code

In the above example, the prepareSocket method first gets the remote hostname to which SSLSocket will connect, and then uses the hostname to determine which TLS protocol to enable. Our HTTP client will now enforce TLS 1.3 for each request, except that the target host name is in the *.internal.system.com format. 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 TLS version when using the Apache HttpClient library. We have seen how to set up the TLS version for all connections or on a per-connection basis.

Original: www.baeldung.com/apache-http…

The code farmer panda

More technical dry goods, please visit my personal website https://pinmost.com, or follow the public number [code farmer panda]