Android enable TLS1.2 for API 19 or older

TLS1.1 and TLS1.2 is not enabled in Android by default for API 19 or below. If an app is running on Device running Android API 19 or older and trying to make REST request to a server that requires TLS1.1 or above, it will fail.

To enable TLS1.2 for API 19 or older, all you have to do is to add the try block below in your Application file. It should be the first thing in the onCreate(), make sure the it happens before any Http client initializes, ex: OkHttp. This should work for all https connections, include making request to REST services, streaming videos, and loading pictures.

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        try {
            // Google Play will install latest OpenSSL
            ProviderInstaller.installIfNeeded(applicationContext)
            val sslContext = SSLContext.getInstance("TLSv1.2")
            sslContext.init(null, null, null)
            sslContext.createSSLEngine()
        } catch (e: GooglePlayServicesRepairableException) {
            e.printStackTrace()
        } catch (e: GooglePlayServicesNotAvailableException) {
            e.printStackTrace()
        } catch (e: NoSuchAlgorithmException) {
            e.printStackTrace()
        } catch (e: KeyManagementException) {
            e.printStackTrace()
        }
    }
}

The dependency required for the ProviderInstaller

implementation com.google.android.gms:play-services-auth:17.0.0

To have more control with the TLS support, refer to this post, but not recommended.

Note, by setting default SSLSocketFactory on HttpsURLConnection will also enable the TLS versions specified in the custom socket factory, for all https connections made with HttpsURLConnection. Again, it’s not recommend as the ProviderInstaller will cover all types connections, but this only works for HttpsURLConnection.

HttpsURLConnection.setDefaultSSLSocketFactory(TLSSocketFactory())

Here is a custom socket factory taken from this post.

public class TLSSocketFactory extends SSLSocketFactory {

    private SSLSocketFactory internalSSLSocketFactory;

    public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, null, null);
        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)) {
            ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"});
        }
        return socket;
    }
}

Here are some posts to create a server and manipulate the TLS support versions.
https://www.codexpedia.com/node-js/nodejs-nginx-with-http-and-https-on-compute-engine/

https://www.codexpedia.com/devops/disable-tls1-0-on-nginx/

https://www.codexpedia.com/devops/nginx-serving-static-media-video-files/

https://www.codexpedia.com/android/android-exoplayer-v2-simple-example/

References:
https://stackoverflow.com/a/30302235/2069407
https://guides.codepath.com/android/Using-OkHttp#enabling-tls-v1-2-on-older-devices
https://developer.android.com/training/articles/security-gms-provider.html

Search within Codexpedia

Custom Search

Search the entire web

Custom Search