How to Set Tls Version on Apache Httpclient

How to set TLS version on apache HttpClient

The solution is:

SSLContext sslContext = SSLContexts.custom()
.useTLS()
.build();

SSLConnectionSocketFactory f = new SSLConnectionSocketFactory(
sslContext,
new String[]{"TLSv1", "TLSv1.1"},
null,
BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);

httpClient = HttpClients.custom()
.setSSLSocketFactory(f)
.build();

This requires org.apache.httpcomponents.httpclient 4.3.x though.

How do I force Apache's CloseableHttpClient to use TLSv1.2?

While creating SSLContext specify that it has to use TLS instead of getting the default one:

SSLContext sslContext = SSLContextBuilder.create().build();

Or:

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(....);

Or simply use:

SSLContext sslContext = SSLContexts.custom().build()

Based on your code here is the running example (it makes the connection to google.com). I have enabled the debug log. Look for negotiated protocol: TLSv1.2 in the log. Now, change the TLS version to 1.1 while creating the http client(new String[] { "TLSv1.1" }), run the program and observe that string 'negotiated protocol..' changed to TLSv1.1.
What you earlier printed that is HTTP protocol version.

import org.apache.http.HttpHost;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.SSLContexts;

import javax.net.ssl.SSLContext;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.StringWriter;

public class ForceTLS12 {
public static void main(String[] args) {
try {
System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");
System.setProperty("org.apache.commons.logging.simplelog.showdatetime","true");
System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http","DEBUG");
System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.wire","DEBUG");
//SSLContext sslContext = SSLContext.getInstance("TLS");
@SuppressWarnings("static-access")
CloseableHttpClient httpclient = HttpClientBuilder.create()
.setSSLSocketFactory(new SSLConnectionSocketFactory(SSLContexts.custom().build(), new String[] { "TLSv1.2" }, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier()))
.build();
HttpHost target = new HttpHost("www.google.com", 443, "https");
//String call = "/vivisimo/cgi-bin/velocity";
HttpGet getRequest = new HttpGet(target.toURI());
CloseableHttpResponse resposne = httpclient.execute(getRequest);

System.out.println(resposne.getEntity().getContentType());
System.out.println("Protocol Version:" + getRequest.getProtocolVersion());
} catch (Exception e) {
e.printStackTrace();
}
}
}

This executable code sample is available at github as well.

Java, Apache HttpClient, TLSv1.2 & OpenJDK 7

jdk.tls.client.protocols only works on Java 8 (and presumably 9) which you aren't using.

https.protocols only works by default in HttpsURLConnection which httpclient doesn't use.

deployment.* only applies to JNLP and applets (if any browser still permits applets) which you aren't using.

An answer to your Q as stated, at least for 4.5, assuming you use HttpClientBuilder or HttpClients (which you didn't say), is to use .useSystemProperties() or .createSystem(), respectively; these do use the same system properties as *URLConnection -- or at least many of them including https.protocols. You should check none of the other properties included in this set is configured to do something you don't want. This does require changing the apps, but not changing them 'to specifically request ... TLSv1.2'.

Other than that you can configure the SSLConnectionSocketFactory to specify the exact protocols allowed as in the Q linked by @pvg, or SSLContexts.custom().useProtocol(String).build() to specify the upper bound -- which is enough for your case because offering the range 'up to 1.2' to a server that requires 1.2 will select 1.2.

How to force Commons HTTPClient 3.1 to use TLS 1.2 only for HTTPS?

Too bad nobody answered; I was able to do it, first you write a CustomHttpSocketFactory, then you do:

String scheme = "https";
Protocol baseHttps = Protocol.getProtocol(scheme);
int defaultPort = baseHttps.getDefaultPort();

ProtocolSocketFactory baseFactory = baseHttps.getSocketFactory();
ProtocolSocketFactory customFactory = new CustomHttpsSocketFactory(baseFactory);

Protocol customHttps = new Protocol(scheme, customFactory, defaultPort);
Protocol.registerProtocol(scheme, customHttps);

A sample custom socket factory code is found here, but instead I did:

public class CustomHttpsSocketFactory implements SecureProtocolSocketFactory
{

private final SecureProtocolSocketFactory base;

public CustomHttpsSocketFactory(ProtocolSocketFactory base)
{
if(base == null || !(base instanceof SecureProtocolSocketFactory)) throw new IllegalArgumentException();
this.base = (SecureProtocolSocketFactory) base;
}

private Socket acceptOnlyTLS12(Socket socket)
{
if(!(socket instanceof SSLSocket)) return socket;
SSLSocket sslSocket = (SSLSocket) socket;
sslSocket.setEnabledProtocols(new String[]{"TLSv1.2" });
return sslSocket;
}

@Override
public Socket createSocket(String host, int port) throws IOException
{
return acceptOnlyTLS12(base.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localAddress, int localPort) throws IOException
{
return acceptOnlyTLS12(base.createSocket(host, port, localAddress, localPort));
}
@Override
public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params) throws IOException
{
return acceptOnlyTLS12(base.createSocket(host, port, localAddress, localPort, params));
}
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException
{
return acceptOnlyTLS12(base.createSocket(socket, host, port, autoClose));
}

}


Related Topics



Leave a reply



Submit