Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enable TLS 1.2 in Android 4.4

I use Retrofit and OkHttp3 for making requests. I konw that in Android 4.4 TLS 1.1 and TLS 1.2 are not enabled by defult. So i'm trying to enable them. But so far i had no sucsess. I read that it could be a problem of the android studio emulator, but i can't make a test on a real device with andoroid 4.4 rigthnow

This is what i have done so far:

private <S> S createService(Class<S> serviceClass) {
    Retrofit retrofit = builder.client(getNewHttpClient()).build();
    return retrofit.create(serviceClass);
}

private OkHttpClient getNewHttpClient() {
    OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(10, TimeUnit.SECONDS)
            .readTimeout(0, TimeUnit.MINUTES); // Disable timeouts for read

    return enableTls12OnPreLollipop(clientBuilder).build();
}


public static OkHttpClient.Builder enableTls12OnPreLollipop(OkHttpClient.Builder client) {
    if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
        try {
            client.sslSocketFactory(new TLSSocketFactory());

            ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
                    .tlsVersions(TlsVersion.TLS_1_2)
                    .build();

            List<ConnectionSpec> specs = new ArrayList<>();
            specs.add(cs);
            specs.add(ConnectionSpec.COMPATIBLE_TLS);
            specs.add(ConnectionSpec.CLEARTEXT);

            client.connectionSpecs(specs);
        } catch (Exception exc) {
            Log.e("OkHttpClientProvider", "Error while enabling TLS 1.2", exc);
        }
    }

    return client;
}

TLSSocketFactory CLASS

public class TLSSocketFactory extends SSLSocketFactory {
private SSLSocketFactory delegate;

public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
    SSLContext context = SSLContext.getInstance("TLS");
    context.init(null, null, null);
    delegate = context.getSocketFactory();
}

@Override
public String[] getDefaultCipherSuites() {
    return delegate.getDefaultCipherSuites();
}

@Override
public String[] getSupportedCipherSuites() {
    return delegate.getSupportedCipherSuites();
}

@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
    return enableTLSOnSocket(delegate.createSocket(s, host, port, autoClose));
}

@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
    return enableTLSOnSocket(delegate.createSocket(host, port));
}

@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
    return enableTLSOnSocket(delegate.createSocket(host, port, localHost, localPort));
}

@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
    return enableTLSOnSocket(delegate.createSocket(host, port));
}

@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
    return enableTLSOnSocket(delegate.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;
}
}

I have tried this but did not work.

My Error is: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xb829bae0: Failure in SSL library, usually a protocol error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:741 0x8d9e3990:0x00000000)

like image 752
Fabio Piunti Avatar asked Aug 25 '17 08:08

Fabio Piunti


People also ask

What version of TLS does Android use?

TLS 1. In Android 10 and higher, TLS 1.3 is enabled by default for all TLS connections.

Is TLS 1.2 automatically enabled?

TLS 1.2 is automatically enabled in Google Chrome version 29 or greater.


1 Answers

Please try this: https://developer.android.com/training/articles/security-gms-provider.html.

It is using https://developers.google.com/android/reference/com/google/android/gms/security/ProviderInstaller, you need to have Google API in your project.

You need to just call in your Application:

@Override
public void onCreate() {
    super.onCreate();
    try {
        ProviderInstaller.installIfNeeded(this);
    } catch (GooglePlayServicesRepairableException | GooglePlayServicesNotAvailableException e) {
        e.printStackTrace();
    }
}

You should also remove your custom SSLfactory.

like image 145
Aleksander Mielczarek Avatar answered Sep 22 '22 12:09

Aleksander Mielczarek