How to set TLS version on apache HttpClient
120,145
Solution 1
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.
Solution 2
This is how I got it working on httpClient 4.5 (as per Olive Tree request):
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(AuthScope.ANY_HOST, 443),
new UsernamePasswordCredentials(this.user, this.password));
SSLContext sslContext = SSLContexts.createDefault();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext,
new String[]{"TLSv1", "TLSv1.1"},
null,
new NoopHostnameVerifier());
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.setSSLSocketFactory(sslsf)
.build();
return httpclient;
Solution 3
HttpClient-4.5,Use TLSv1.2 ,You must code like this:
//Set the https use TLSv1.2
private static Registry<ConnectionSocketFactory> getRegistry() throws KeyManagementException, NoSuchAlgorithmException {
SSLContext sslContext = SSLContexts.custom().build();
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,
new String[]{"TLSv1.2"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
return RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslConnectionSocketFactory)
.build();
}
public static void main(String... args) {
try {
//Set the https use TLSv1.2
PoolingHttpClientConnectionManager clientConnectionManager = new PoolingHttpClientConnectionManager(getRegistry());
clientConnectionManager.setMaxTotal(100);
clientConnectionManager.setDefaultMaxPerRoute(20);
HttpClient client = HttpClients.custom().setConnectionManager(clientConnectionManager).build();
//Then you can do : client.execute(HttpGet or HttpPost);
} catch (KeyManagementException | NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
Solution 4
Using the HttpClientBuilder
in HttpClient 4.5.x with a custom HttpClientConnectionManager
with the defaults of HttpClientBuilder
:
SSLConnectionSocketFactory sslConnectionSocketFactory =
new SSLConnectionSocketFactory(SSLContexts.createDefault(),
new String[] { "TLSv1.2" },
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager =
new PoolingHttpClientConnectionManager(
RegistryBuilder.<ConnectionSocketFactory> create()
.register("http",
PlainConnectionSocketFactory.getSocketFactory())
.register("https",
sslConnectionSocketFactory)
.build());
// Customize the connection pool
CloseableHttpClient httpClient = HttpClientBuilder.create()
.setConnectionManager(poolingHttpClientConnectionManager)
.build()
Without a custom HttpClientConnectionManager
:
SSLConnectionSocketFactory sslConnectionSocketFactory =
new SSLConnectionSocketFactory(SSLContexts.createDefault(),
new String[] { "TLSv1.2" },
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
CloseableHttpClient httpClient = HttpClientBuilder.create()
.setSSLSocketFactory(sslConnectionSocketFactory)
.build()
Solution 5
For HttpClient-4.1 using TLSv1.2, code would go something like this:
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, null, new SecureRandom());
SSLSocketFactory sf = new SSLSocketFactory(sslContext);
Scheme httpsScheme = new Scheme("https", 443, sf);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(httpsScheme);
ClientConnectionManager cm = new SingleClientConnManager(schemeRegistry);
HttpClient client = new DefaultHttpClient(cm);
// Use client to make the connection and get the results.
Related videos on Youtube
Author by
Oliveira
Updated on May 28, 2020Comments
-
Oliveira almost 4 years
How can I change the supported TLS versions on my HttpClient?
I'm doing:
SSLContext sslContext = SSLContext.getInstance("TLSv1.1"); sslContext.init( keymanagers.toArray(new KeyManager[keymanagers.size()]), null, null); SSLSocketFactory socketFactory = new SSLSocketFactory(sslContext, new String[]{"TLSv1.1"}, null, null); Scheme scheme = new Scheme("https", 443, socketFactory); SchemeRegistry schemeRegistry = new SchemeRegistry(); schemeRegistry.register(scheme); BasicClientConnectionManager cm = new BasicClientConnectionManager(schemeRegistry); httpClient = new DefaultHttpClient(cm);
But when I check the created socket, it still says the supported protocols are TLSv1.0, TLSv1.1 and TLSv1.2.
In reality I just want it to stop using TLSv1.2, for this specific HttpClient.
-
IgorGanapolsky about 8 yearsWhat version of HttpClient are you trying to target?
-
-
douglaslps almost 9 yearsIt seems that this has been deprecated. Can you please update to reflect new httpClient versions?
-
Oliveira almost 9 yearsI know. Unfortunately I didn't investigate too much on how to get it working with the new httpClient version, so I'm using an old version. But let me know if you get it working.
-
Anand Bhat over 8 yearsPlease note that the code snippet above uses NoopHostnameVerifier which essentially turns hostname verification off. In most cases, this is a very bad thing.
-
AntonioOtero about 8 yearsWorked perfectly for me. I applied this solution to force calls to use TLSv1.2 since vendors like PayPay and UPS' API are now enforcing it. Java7 defaults to TLSv1, Java8 defaults to TLSv1.2 but I can't upgrade Java right now, so this post really helped me.
-
IgorGanapolsky about 8 yearsWhat if I want to do something similar with httpclient 4.1.1?
-
Christopher Schultz almost 8 years@Skynet The technique should be valid, but the specific TLS protocols and cipher suites are generally dictated by the underlying JVM. So you'll have to check out the protocol support for Android < 4.1.
-
Gaurav Rawat almost 8 years@Oliveira does setting system environment https.protocols=TLSv1,TLSv1.1 not achive the same result ?
-
Oliveira almost 8 years@GauravRawat maybe. But then you change it for all the http clients, instead of just one.
-
Gaurav Rawat almost 8 yearsThat can still be done by using SSL connection socket factory.getSystemSocketFactory and be managed for the app easily, that shouldn't charge it for all but it's UpTo your choice anyways
-
Shrikant Thakare over 7 years@AntonioOtero did you get it working with JDK7 ? I created client using above method.But I see that during SSL handshake (ClientHello) the protocol listed is TLSv1. I did set https.protocols also but no effect.Using httpclient-4.3.3.jar. Do you mean that this only changes the supported protocol on socket but the underlying SSL handshake is still controlled by JSSE API ? I mean Apache HttpClient does not implement any of the TLS protocol aspects. It relies on JSSE APIs to do TLS/SSL handshaking and to establish secure SSL sessions ?
-
AntonioOtero over 7 years@ShrikantThakare I didn´t have those problems, I see TLSv1.2 listed. The only change I did to the code in this answer was to remove TLSv1.1 from the parameters of the factory, i.e. new String[]{"TLSv1.2"} Hope this helps
-
Christopher Schultz about 7 years@comeOnGetIt Java 6 mostly does not support anything higher than TLS 1.0 (stackoverflow.com/questions/33364100/…). Java 6 should be dead at this point, anyway.
-
Bertl almost 7 yearsNope. Does NOT work server side, only in client side JVM Applets / Webstart.
-
jebeaudet over 6 years@Oliveira When you use
HttpClientBuilder
, this will work only if you enablesystemProperties
since it's off by default. -
John Russell about 6 yearsCan one just use the org.apache.http.conn.ssl.DefaultHostnameVerifier ?
-
рüффп about 6 yearsIt does not seem to work as well if you use the apache httpclient (tested with 3 and 4). I am not sure if these settings are really necessary if the other solutions are implemented.
-
Mohnish almost 6 yearsYes, if JDK makes the connection using
URL#openConnection()
, but these doesn't work with Apache HttpClient. Question is specifically tagged apache-httpclient-4.x -
Horrorgoogle about 5 yearswhat is useTLS()? what should be implementing in this?any idea?
-
Oliveira about 5 years
-
JonnyJD almost 5 yearsThis also works with Apache http client together with useSystemProperties()
-
JonnyJD almost 5 years
-Dhttps.protocols
also works with Apache http client together with useSystemProperties() -
cviniciusm almost 4 years@ShrikantThakare which version and build of Java did you use, please?