why do I get SSLProtocolExcepetion: Handshake failed when trying to send http request?

-1

im trying to send a JSON object from android to a server I wrote in NodeJS. the server is running and working, I can POST to it using Postman software. but when I try to send a JSON using android, im getting a SSLProtocolException: SSL handshake aborted.

the full log:

javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xd7a38728: Failure in SSL library, usually a protocol error error:100000f7:SSL routines:OPENSSL_internal:WRONG_VERSION_NUMBER (third_party/openssl/boringssl/src/ssl/tls_record.cc:242 0xbc4ddce6:0x00000000)

I used the code from here trying to send the http request: How To Send json Object to the server from my android app

after I got the SSLProtocolException I tried this solutions:

  1. SSLSocket exception handshake error when trying to send to SSLServerSocket

  2. Javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: Failure in SSL library, usually a protocol error

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

but nothing seemed to work.

I'm running on localhost, but it said one time I can't connect to local host that why I changed the url in the code below.

my code:

public class SendProductJsonTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... strings) {
    String data = "";

    HttpURLConnection httpURLConnection = null;
    try {
        httpURLConnection = (HttpURLConnection) new URL(strings[0]).openConnection();
        httpURLConnection.setRequestMethod("POST");

        httpURLConnection.setDoOutput(true);

        DataOutputStream wr = new DataOutputStream(httpURLConnection.getOutputStream());
        wr.writeBytes("PostData="+strings[1]);
        wr.flush();
        wr.close();

        InputStream in = httpURLConnection.getInputStream();
        InputStreamReader inputStreamReader = new InputStreamReader(in);

        int inputStreamData = inputStreamReader.read();

        while (inputStreamData != -1) {

            char current = (char) inputStreamData;

            inputStreamData = inputStreamReader.read();

            data += current;

        }

    } catch (Exception e) {
        Log.d("ccb", "doInBackground16: "+e.getCause());
        Log.d("ccb", "doInBackground17: "+e.getMessage());
        e.printStackTrace();
    } finally {
        if (httpURLConnection != null) {
            httpURLConnection.disconnect();
        }
    }
    return data;
}

@Override
protected void onPostExecute(String s) {
    super.onPostExecute(s);
    Log.d("ccb", "onPostExecute: "+s);
}

}

how I'm calling the http request:

findViewById(R.id.sendBtn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO: in a click it will gather all data from the user, turn it into a json object, and will send it to the DB;
                nameOfProduct = ((EditText)findViewById(R.id.etNameOfPr)).getText().toString();
                serialOfProduct = ((EditText)findViewById(R.id.etSerialOfPr)).getText().toString();
                priceOfProduct = ((EditText)findViewById(R.id.etPriceOfPr)).getText().toString();

                try {
                    productJson(nameOfProduct, serialOfProduct, priceOfProduct, getGenderRB(), uriList, getColorsCB(), getSizeCB(), new JSONMadeListener() {
                        @Override
                        public void onJSONMade(JSONObject object) {
                            try {
                                SSLContext.getInstance("TLSv1.2");
                            } catch (NoSuchAlgorithmException e) {
                                e.printStackTrace();
                            }
                            try {
                                ProviderInstaller.installIfNeeded(getApplicationContext());
                            } catch (GooglePlayServicesRepairableException e) {
                                e.printStackTrace();
                            } catch (GooglePlayServicesNotAvailableException e) {
                                e.printStackTrace();
                            }
                            new SendProductJsonTask().execute("https://10.0.2.2:4000/products/add",object.toString());
                        }
                    });
                } catch (JSONException e) {
                    e.printStackTrace();
                }
java
android
ssl
asked on Stack Overflow Jun 18, 2020 by pythwan

1 Answer

1
... .execute("https://10.0.2.2:4000/products/add",object.toString());

I'm pretty sure that all you did with replace a working http:// with https:// and hoped that the server will magically be accessible by HTTPS this way. Only this does not work: the server actually has to implement and properly setup HTTPS including certificates etc. If this is not done you'll get something like this:

... routines:OPENSSL_internal:WRONG_VERSION_NUMBER ...

This is because the servers plain HTTP response (likely an error message about an invalid request) is blindly interpreted as a HTTPS response by the client. Given that a HTTPS response contains the TLS version number at a specific byte offset the client blindly interprets these bytes as TLS version and then complains about an unsupported TLS version.

To make sure that your server properly serves HTTPS try with a browser: if it does not work there it will likely not work within your app too.

answered on Stack Overflow Jun 18, 2020 by Steffen Ullrich

User contributions licensed under CC BY-SA 3.0