i am using OKHttp for my project. i want to enable TLSv1.2 for my service call. can any body tell me how to enable it.
-
how does it work for you? Please tell me I can't ask question on stackoverflow – Zeeshan Nov 26 '15 at 23:39
-
This solution fixed my problem : https://stackoverflow.com/a/45853669/3448003 – Bajrang Hudda Aug 24 '17 at 07:15
5 Answers
See OkHttp’s HTTPS documentation.
ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.cipherSuites(
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
.build();
OkHttpClient client = ...
client.setConnectionSpecs(Collections.singletonList(spec));

- 39,078
- 8
- 121
- 128
-
4as the documentation says - this would only work on android 5.0 or higher – Shlomi Apr 21 '15 at 08:08
-
3It doesn't even work on Android 5.0. I get SSL HandshakeException. – IgorGanapolsky Oct 22 '15 at 20:53
-
@ShanXeeshi explain how it doesn’t work? It’s likely a problem that your webserver isn’t configured for TLS 1.2. – Jesse Wilson Nov 27 '15 at 05:20
-
now what should i do for below lolipop because its not working ? I am getting this exception **UnknownServiceException Unable to find acceptable protocols. isFallback=false, modes=[ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, ....], tlsVersions=[TLS_1_2], supportsTlsExtensions=true)], supported protocols=[SSLv3, TLSv1]** – Zeeshan Nov 27 '15 at 20:44
-
Hi @jesse-wilson, I've tried - unfortunately it doesn't work for me `ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) .allEnabledCipherSuites() .allEnabledTlsVersions() .build();` I still have the error: `Retrofit: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.` – Kirill Vashilo Aug 26 '16 at 11:25
-
-
Thanks, that's the simplest way to get it work! Tested on Android 7.0 – Fragment May 23 '17 at 14:23
-
the same as @IgorGanapolsky, I got `javax.net.ssl.SSLHandshakeException:HANDSHAKE_FAILURE_ON_CLIENT_HELLO` – Oleksandr Nos Apr 22 '22 at 13:02
As far as I know OKHttp does not include own SSL/TLS libraries, therefore it just uses the standard SSLSocket provided by Android.
What TLS versions are supported (and enabled) depends on the used Android version.
On some phones TLS 1.2 is supported but not enabled by default (as far as I remember this affects phones with Android 4.1/4.2/4.4). In such cases you could enable it by implementing a custom wrapper SSLSocketFactory that uses internally the default SSLSocketFactory and calls setEnabledProtocols(new String[]{"TLS1.2"})
on every Socket that is created.
On device with Google Services installed the preferred way to enable TLS 1.2 on old Android 4.x device is using ProviderInstaller.

- 39,162
- 17
- 99
- 152
-
1Thanks for this sugestion. I`ve combined it with https://stackoverflow.com/a/38962842/5251437. If the `ProviderInstaller` fails (or exception is thrown) I`m trying to use custom SSLSoketFactory that sets enabled protocols... – convexHull Jun 29 '18 at 09:28
Check My Code!!Working perfect!
private void checkTls() {
if (android.os.Build.VERSION.SDK_INT < 21) {
try {
ProviderInstaller.installIfNeededAsync(this, new ProviderInstaller.ProviderInstallListener() {
@Override
public void onProviderInstalled() {
}
@Override
public void onProviderInstallFailed(int i, Intent intent) {
}
});
} catch (Exception e) {
finish();
e.printStackTrace();
}
}
}

- 225
- 3
- 6
-
2Use this before you call web service. Just need to call once in your app – wei wang Aug 15 '16 at 20:50
-
5This solution will not work for everyone. The ProviderInstaller class comes from Google Play Services, and Google Play Services is not available on every Android device. Most notably in China, where GPS is disallowed. – EJK Nov 23 '16 at 20:11
Turns out my solution is very similar to Ken's (except in Java). I found it here although had to make a couple of small changes to get it to work. Hopefully this works 'out of the box' for others.
public class TLSSocketFactoryCompat extends SSLSocketFactory {
private SSLSocketFactory internalSSLSocketFactory;
public TLSSocketFactoryCompat() throws KeyManagementException, NoSuchAlgorithmException {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, null, null);
internalSSLSocketFactory = context.getSocketFactory();
}
public TLSSocketFactoryCompat(TrustManager[] tm) throws KeyManagementException, NoSuchAlgorithmException {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tm, new java.security.SecureRandom());
internalSSLSocketFactory = context.getSocketFactory();
}
@Override
public String[] getDefaultCipherSuites() {
return internalSSLSocketFactory.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return internalSSLSocketFactory.getSupportedCipherSuites();
}
@Override
public Socket createSocket() throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket());
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
}
private Socket enableTLSOnSocket(Socket socket) {
if(socket != null && (socket instanceof SSLSocket)) {
//Create list of supported protocols
ArrayList<String> supportedProtocols = new ArrayList<>();
for (String protocol : ((SSLSocket)socket).getEnabledProtocols()) {
//Log.d("TLSSocketFactory", "Supported protocol:" + protocol);
//Only add TLS protocols (don't want ot support older SSL versions)
if (protocol.toUpperCase().contains("TLS")) {
supportedProtocols.add(protocol);
}
}
//Force add TLSv1.1 and 1.2 if not already added
if (!supportedProtocols.contains("TLSv1.1")) {
supportedProtocols.add("TLSv1.1");
}
if (!supportedProtocols.contains("TLSv1.2")) {
supportedProtocols.add("TLSv1.2");
}
String[] protocolArray = supportedProtocols.toArray(new String[supportedProtocols.size()]);
/*for (int i = 0; i < protocolArray.length; i++) {
Log.d("TLSSocketFactory", "protocolArray[" + i + "]" + protocolArray[i]);
}*/
//enable protocols in our list
((SSLSocket)socket).setEnabledProtocols(protocolArray);
}
return socket;
}
}
Usage:
OkHttpClient httpClient = new OkHttpClient();
//Add Custom SSL Socket Factory which adds TLS 1.1 and 1.2 support for Android 4.1-4.4
try {
httpClient.setSslSocketFactory(new TLSSocketFactoryCompat());
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}

- 7,858
- 11
- 48
- 81

- 3,723
- 1
- 23
- 36
-
I had high hopes for this but I see `Enabling TLS 1.2 Enabling TLS 1.2 Enabling TLS 1.2 Enabling TLS 1.2 Enabling TLS 1.2 Enabling TLS 1.2 Enabling TLS 1.2 Enabling TLS 1.2 javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0x5ff7f518: Failure in SSL library, usually a protocol error error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure (external/openssl/ssl/s3_pkt.c:1256 0x5fe90e28:0x00000003) at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:568)` – Someone Somewhere Jul 11 '16 at 10:43
-
at least it tries enableTLSOnSocket() 8 times, over the course of a few seconds, before giving up. – Someone Somewhere Jul 11 '16 at 10:43
-
Someone Somewhere, I'm not sure the error you're getting is actually related (could be a cert issue) but it reminded me that I updated this class to ensure that the list of supported protocols were only added to. I think before it may have left only TLS 1.1 and 1.2 enabled. Hopefully this helps. – aaronmarino Jul 11 '16 at 16:09
-
1Hi Aaron, I found out today that the issue I was seeing was due to firmware issues with the device. The app can do no magic if the underlying firmware is just broken. – Someone Somewhere Jul 15 '16 at 12:37
-
how can I implement for httpclient?? I mean to how to set setSslSocketFactory? – Horrorgoogle Mar 20 '19 at 03:03
-
Why am I getting `java.lang.IllegalStateException: Unable to extract the trust manager on Platform, sslSocketFactory is class` – francis Mar 20 '21 at 14:54
This is basically the same as the answer above but I feel like a code sample would be useful for anyone else who lands here and isn't up to speed on navigating the java ssl landscape.
What ultimately ended up working for me was based on the issue reported here: https://github.com/mattleibow/square-bindings/issues/1
from this gist https://gist.github.com/mattleibow/c8abfa323db094b820cc
Note these code samples are in C# / Xamarin but can be translated to java fairly easily.
internal class CompleteSSLSocketFactory : SSLSocketFactory
{
private readonly SSLSocketFactory innerFactory;
public CompleteSSLSocketFactory (SSLSocketFactory innerFactory)
{
this.innerFactory = innerFactory;
}
public override string[] GetDefaultCipherSuites ()
{
return innerFactory.GetDefaultCipherSuites ();
}
public override string[] GetSupportedCipherSuites ()
{
return innerFactory.GetSupportedCipherSuites ();
}
public override Socket CreateSocket ()
{
return MakeSocketSafe (innerFactory.CreateSocket ());
}
public override Socket CreateSocket (Socket s, string host, int port, bool autoClose)
{
return MakeSocketSafe (innerFactory.CreateSocket (s, host, port, autoClose));
}
public override Socket CreateSocket (string host, int port)
{
return MakeSocketSafe (innerFactory.CreateSocket (host, port));
}
public override Socket CreateSocket (string host, int port, InetAddress localHost, int localPort)
{
return MakeSocketSafe (innerFactory.CreateSocket (host, port, localHost, localPort));
}
public override Socket CreateSocket (InetAddress host, int port)
{
return MakeSocketSafe (innerFactory.CreateSocket (host, port));
}
public override Socket CreateSocket (InetAddress address, int port, InetAddress localAddress, int localPort)
{
return MakeSocketSafe (innerFactory.CreateSocket (address, port, localAddress, localPort));
}
private Socket MakeSocketSafe (Socket socket)
{
var sslSocket = socket as SSLSocket;
if (sslSocket != null) {
// enable all supported protocols for this socket
sslSocket.SetEnabledProtocols (sslSocket.GetSupportedProtocols ());
sslSocket.SetEnabledCipherSuites (sslSocket.GetSupportedCipherSuites ());
}
return socket;
}
}
And then calling it like:
// this.client is an OkHttpClient
if (Android.OS.Build.VERSION.SdkInt < BuildVersionCodes.Lollipop) {
this.client.SetSslSocketFactory(new CompleteSSLSocketFactory(HttpsURLConnection.DefaultSSLSocketFactory));
}
This worked for me, tested on API 19.

- 1
- 1

- 1,124
- 13
- 27