javax.net.ssl.SSLException: SSL handshake aborted on android old devices

Use this in your code before making any network call

/**
 * Initialize SSL
 * @param mContext
 */
public static void initializeSSLContext(Context mContext){
    try {
        SSLContext.getInstance("TLSv1.2");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    try {
        ProviderInstaller.installIfNeeded(mContext.getApplicationContext());
    } catch (GooglePlayServicesRepairableException e) {
        e.printStackTrace();
    } catch (GooglePlayServicesNotAvailableException e) {
        e.printStackTrace();
    }
}

I had the same problem and this piece of code solved my problem. FYI: I was using retrofit library for making network calls

You need to include below line in build.gradle

implementation 'com.google.android.gms:play-services-safetynet:17.0.0

Thanks @Houman for the above input


Different Android API levels have different support for SSL/TLS protocols versions, for details see in Android Documention - https://developer.android.com/reference/javax/net/ssl/SSLSocket.html

To enable TLS 1.1 and 1.2 you need to create a custom SSLSocketFactory - https://blog.dev-area.net/2015/08/13/android-4-1-enable-tls-1-1-and-tls-1-2/

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;
    }
}

And then use it in your connection

HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
TLSSocketFactory socketFactory = new TLSSocketFactory();
conn.setSSLSocketFactory(socketFactory);
conn.connect();

Tags:

Android