0

I'm trying to create my first Android app and I have an issue.

I have web service with https protocol, to get the data from the server I use AsyncHttpClient library,

it has been working with http, but once I've changed it to https it's gives me an error:

No peer certificate

I did some research online, I found some advice how to fix it but I was abel to make it works.

This are just some of the links I tried: link 1 link 2

My code to call a web service:

    AsyncHttpClient client = new AsyncHttpClient();

    client.get(QUERY_URL,
    new JsonHttpResponseHandler() {

            @Override
            public void onSuccess(JSONObject jsonObject) {

                Log.d("test", jsonObject.toString());
            }

            @Override
            public void onFailure(int statusCode, Throwable throwable, JSONObject error) {

                Log.e("test", "Error: " + statusCode + " " + throwable.getMessage());
            }
        });

Maybe there is some other library which you recommend for calling https async?

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Greg
  • 25,317
  • 6
  • 53
  • 62

1 Answers1

1

This is the code I use for SSL networking:

private class MobHawkCheck extends AsyncTask<String, Void, JSONObject> {

        protected JSONObject doInBackground(String... params) {
            JSONObject json = null;
            try {
                // Load CAs from an InputStream
                // (could be from a resource or ByteArrayInputStream or ...)
                CertificateFactory cf = CertificateFactory.getInstance("X.509");
                // From https://www.washington.edu/itconnect/security/ca/load-der.crt
                InputStream cert = mActivity.getResources().openRawResource(R.raw.mycertificate);
                InputStream caInput = new BufferedInputStream(cert);
                Certificate ca;
                try {
                    ca = cf.generateCertificate(caInput);
                    System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
                } finally {
                    caInput.close();
                }
                // Create a KeyStore containing our trusted CAs
                String keyStoreType = KeyStore.getDefaultType();
                KeyStore keyStore = KeyStore.getInstance(keyStoreType);
                keyStore.load(null, null);
                keyStore.setCertificateEntry("ca", ca);

                // Create a TrustManager that trusts the CAs in our KeyStore
                String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
                TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
                tmf.init(keyStore);

                // Create an SSLContext that uses our TrustManager
                SSLContext context = SSLContext.getInstance("TLS");
                context.init(null, tmf.getTrustManagers(), null);

                // Tell the URLConnection to use a SocketFactory from our SSLContext
                URL url = new URL("https://mysecureurl.com");
                HttpsURLConnection urlConnection =
                        (HttpsURLConnection)url.openConnection();
                urlConnection.setSSLSocketFactory(context.getSocketFactory());

                BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
                StringBuilder total = new StringBuilder();
                String line;
                while ((line = r.readLine()) != null) {
                    total.append(line);
                }
                json = new JSONObject(total.toString());
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            } catch (KeyManagementException e) {
                e.printStackTrace();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (KeyStoreException e) {
                e.printStackTrace();
            } catch (CertificateException e) {
                e.printStackTrace();
            }
            return json;
        }

        protected void onPostExecute(JSONObject result) {
            //TODO parse the result JSONObject
        }
    }

Take note that I use my own .crt file. You should generate yours with the data of your server certificate.

Nimantha
  • 6,405
  • 6
  • 28
  • 69
reixa
  • 6,903
  • 6
  • 49
  • 68
  • Can you add example how do you call this class? Do you know how can I get the cert file (.crt) if I haven't got access to the server, I just call the server? – Greg Feb 26 '14 at 15:47
  • @Greg you can easily do it following this question http://superuser.com/questions/97201/how-to-save-a-remote-server-ssl-certificate-locally-as-a-file the second answer should be the right one because you don't have access to the server. I call that function like any other AsyncTask new MobHawkCheck().execute(); – reixa Feb 26 '14 at 16:22
  • I tried your solution but I have an error, this is just part of it: FATAL EXCEPTION: AsyncTask #1 An error occured while executing doInBackground() Can't create handler inside thread that has not called Looper.prepare() – Greg Feb 26 '14 at 16:37
  • That´s because in my code I parse the result from server and then send a message to a handler on postExecute. Just remove that and parse it you way. – reixa Feb 26 '14 at 16:40
  • In onPostExecute I commented out your code and now there is just Lod.d("test", result); line and there is this error after I run the code. – Greg Feb 26 '14 at 16:41
  • There´s no other reference to the Handler in the code. Have you cleaned your project before running it on the device/emulator? – reixa Feb 26 '14 at 16:48
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/48501/discussion-between-axierjhtjz-and-greg) – reixa Feb 26 '14 at 16:48