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

Exception or error:

I have android application that was working fine for most of devices
Recently some hackers tried to make DDOS attack on our servers that force us to add some security and some firewalls

not some devices are not working and give me the following exception

javax.net.ssl.SSLException: SSL handshake aborted: ssl=0x63eb8240: I/O error during system call, Connection reset by peer 

can any one please tell me what is the problem now and how can I solve it ?

EDIT

this is the code of my execute method

public static BaseResponse execute(Context context, BaseRequest request) {

    mStartTime = System.nanoTime();

    BaseResponse response = new BaseResponse();
    DataOutputStream outputStream;
    try {
        URL url = new URL(request.getURL());
        HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
        urlConnection.setConnectTimeout(TIMEOUT_DURATION);
        urlConnection.setReadTimeout(TIMEOUT_DURATION);
        urlConnection.setRequestMethod(request.getRequestType().getValue());
        urlConnection.addRequestProperty("Accept", "application/json");
        urlConnection.addRequestProperty("Content-Type","application/json");
        urlConnection.setRequestProperty("Accept-Charset", CHARACTER_SET);
        urlConnection.addRequestProperty("Device-Id", PhoneUtils.getDeviceId(context));
        urlConnection.addRequestProperty("Version-Number", PhoneUtils.getAppVersion(context));


        TLSSocketFactory socketFactory = new TLSSocketFactory();
        urlConnection.setSSLSocketFactory(socketFactory);

        switch (request.getRequestType()) {
            case POST:
            case PUT:
                urlConnection.setDoOutput(true);
                if (request.getStringEntity() != null) {
                    outputStream = new DataOutputStream(urlConnection.getOutputStream());
                    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, CHARACTER_SET));
                    writer.write(request.getStringParam());
                    writer.close();
                    outputStream.flush();
                    outputStream.close();
                }

                break;
            case GET:
                urlConnection.setDoOutput(false);
                break;
        }

        urlConnection.connect();

        try {
            if (urlConnection.getResponseCode() == STATUS_OK) {
                InputStream inputStream = new BufferedInputStream(urlConnection.getInputStream());
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                StringBuilder result = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    result.append(line);
                }

                inputStream.close();
                response.setResponse(convertStringToJSONObject(result.toString()));
            } else {
                response.setResponse(null);
            }
        } catch (Exception ex) {
            response.setAppError(AppError.DATA_ERROR);
        }
    } catch (MalformedURLException e) {
        e.printStackTrace();
        response.setAppError(AppError.PARSING_ERROR);
    } catch (IOException e) {
        e.printStackTrace();
        response.setAppError(AppError.DATA_ERROR);
    } catch (Exception e) {
        e.printStackTrace();
        response.setAppError(AppError.DATA_ERROR);
    }

    return response;
}
How to solve:

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

###

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();

Leave a Reply

Your email address will not be published. Required fields are marked *