Android Enable TLSv1.2 in OKHttp

I am using OKHttp for my project. I want to enable TLSv1.2 for my office call. can any body tell me how to turn it on.

+11
android ssl
Mar 25 '15 at 7:17
source share
5 answers

See OkHttps 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)); 
+6
Mar 25 '15 at 12:03
source

As far as I know OKHttp does not include native SSL / TLS libraries, so it just uses the standard SSLSocket provided by Android.

Which versions of TLS are supported (and included) depends on the version of Android you are using. On some phones, TLS 1.2 is supported but not enabled by default. In such cases, you can enable it by implementing the custom SSLSocketFactory shell, which internally uses the default SSLS file and calls setEnabledProtocols(new String{"TLS1.2"}) for each Socket created.

+5
Mar 25 '15 at 10:09
source

Check my code! Work perfectly!

 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(); } } } 
+2
Aug 15 '16 at 20:50
source

Turns out my solution is very similar to Ken (except Java). I found it here , although I had to make a couple of small changes to make it work. Hope 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; } 

}

Using:

  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(); } 
+1
Jun 17 '16 at 15:01
source

This is basically the same as the answer above , but I feel that the code sample would be useful to anyone who has landed here and does not have time to navigate the java ssl landscape.

What ultimately ended for me was based on the issue that was reported here: https://github.com/mattleibow/square-bindings/issues/1
from this gist https://gist.github.com/mattleibow/c8abfa323db094b820cc

Please note that these code samples are in C # / Xamarin, but can be easily translated into java.

 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 call 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.

0
Mar 03 '16 at 13:44
source



All Articles