Skip to content Skip to sidebar Skip to footer

How To Use Self-signed Ssl In Android Network Library (ion)?

Using this network library: https://github.com/koush/ion As the current status is development, I would like to use self-signed SSL cert The library forum has some discussion: https

Solution 1:

For your issue, IMO, you can refer to my following sample code. I have tested with my web service (Asp.Net WebAPI). Hope it helps!

publicclassMainActivityextendsAppCompatActivity {

    privateContext mContext = this;

    @OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            // cert file stored in \app\src\main\res\rawInputStream caInput = getResources().openRawResource(R.raw.your_cert);

            Certificate ca = cf.generateCertificate(caInput);
            caInput.close();

            KeyStore keyStore = KeyStore.getInstance("BKS");
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", ca);

            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);

            TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers());

            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, wrappedTrustManagers, null);

            AsyncSSLSocketMiddleware sslMiddleWare = Ion.getDefault(mContext).getHttpClient().getSSLSocketMiddleware();
            sslMiddleWare.setTrustManagers(wrappedTrustManagers);
            sslMiddleWare.setHostnameVerifier(getHostnameVerifier());
            sslMiddleWare.setSSLContext(sslContext);

            // Post application/x-www-form-urlencoded and read a StringIon.with(mContext)
                    .load("https://yourserver/token")
                    .setBodyParameter("grant_type", "password")
                    .setBodyParameter("username", "bnk")
                    .setBodyParameter("password", "bnk123456789")
                    .asString()
                    .setCallback(newFutureCallback<String>() {
                        @OverridepublicvoidonCompleted(Exception e, String result) {
                            if (result != null) {
                                Log.i("ionSample", result);
                            } elseif (e != null) {
                                e.printStackTrace();
                            }
                        }
                    });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    privateHostnameVerifiergetHostnameVerifier() {
        returnnewHostnameVerifier() {
            @Overridepublicbooleanverify(String hostname, SSLSession session) {
                returntrue;
                // or the following:// HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();// return hv.verify("www.yourserver.com", session);
            }
        };
    }

    privateTrustManager[] getWrappedTrustManagers(TrustManager[] trustManagers) {
        final X509TrustManager originalTrustManager = (X509TrustManager) trustManagers[0];
        returnnewTrustManager[]{
                newX509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return originalTrustManager.getAcceptedIssuers();
                    }

                    publicvoidcheckClientTrusted(X509Certificate[] certs, String authType) {
                        try {
                            if (certs != null && certs.length > 0){
                                certs[0].checkValidity();
                            } else {
                                originalTrustManager.checkClientTrusted(certs, authType);
                            }
                        } catch (CertificateException e) {
                            Log.w("checkClientTrusted", e.toString());
                        }
                    }

                    publicvoidcheckServerTrusted(X509Certificate[] certs, String authType) {
                        try {
                            if (certs != null && certs.length > 0){
                                certs[0].checkValidity();
                            } else {
                                originalTrustManager.checkServerTrusted(certs, authType);
                            }
                        } catch (CertificateException e) {
                            Log.w("checkServerTrusted", e.toString());
                        }
                    }
                }
        };
    }   
}

Logcat output:

I/ionSample: {"access_token":"oS1SHxck8TzidTL...P-_6VFjRlDsjF9_A0JONu59rzYOVQV...ka78pHSvRPB5YrrBlHsF562Ay__Jd0MDfpOB0SRML2N8O3XPZK8woV4vjASzfGEzi7KJMmY8pkM_-P9ohHhWPD3PtgRahiqTUSapdpg6n197uJxdQWyU","token_type":"bearer","expires_in":2591999,"userName":"bnk",".issued":"Wed, 06 Jan 2016 06:26:45 GMT",".expires":"Fri, 05 Feb 2016 06:26:45 GMT"}

Solution 2:

As the current status is development, I would like to ignore the SSL checking , but instead of replace https with http

Use Delete, Backspace, or equivalent operations to remove the s from the https scheme in your URL. Done.

This assumes that your server supports plain HTTP. If it does not, talk to whoever is maintaining the server.

Any experience in bypass the SSL checking (with using self sign cert) before?

Self-signed SSL certificates are not used to "bypass the SSL checking". If you are connecting to an HTTPS server that is using a self-signed certificate, then you configure Ion (or other HTTP clients) to recognize that certificate.

You "bypass the SSL checking" by not requesting an https:// URL, and having a server that supports a plain http:// URL.

And the problem is how to construct the sslContext obj / trust managers ?

If you actually have a server that is using a self-signed SSL certificate, you can use my CWAC-Security library to create the TrustManager[]. Or, follow the Java snippets in Nikolay Elenkov's old blog post, adapting them for use with Ion.

Solution 3:

1. Generate the self signed certificate by openssl libarary.
http://stackoverflow.com/questions/10175812/how-to-create-a-self-signed-certificate-with-openssl2. Import the same certificate or its root certificate to your server(ISS or apache.
3. Use following code in client 
// Load CAs from an InputStream
// (could be from a resource or ByteArrayInputStream or ...)CertificateFactorycf= CertificateFactory.getInstance("X.509");
// From https://www.washington.edu/itconnect/security/ca/load-der.crtInputStreamcaInput=newBufferedInputStream(newFileInputStream("load-der.crt"));
Certificate ca;
try {
    ca = cf.generateCertificate(caInput);
    System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
    caInput.close();
}

// Create a KeyStore containing our trusted CAsStringkeyStoreType= KeyStore.getDefaultType();
KeyStorekeyStore= KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);

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

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

// Tell the URLConnection to use a SocketFactory from our SSLContextURLurl=newURL("https://certs.cac.washington.edu/CAtest/");
HttpsURLConnectionurlConnection=
    (HttpsURLConnection)url.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
InputStreamin= urlConnection.getInputStream();
copyInputStreamToOutputStream(in, System.out);

http://developer.android.com/training/articles/security-ssl.html

Solution 4:

try {
            TrustManager[] wrappedTrustManagers = newTrustManager[]{
                    newX509TrustManager() {
                        publicvoidcheckClientTrusted(X509Certificate[] chain, String authType) {
                        }

                        publicvoidcheckServerTrusted(X509Certificate[] chain, String authType) {
                        }

                        public X509Certificate[] getAcceptedIssuers() {
                            returnnew X509Certificate[]{};
                        }
                    }
            };

            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, wrappedTrustManagers, null);

            AsyncSSLSocketMiddleware sslMiddleWare = Ion.getDefault(this).getHttpClient().getSSLSocketMiddleware();
            sslMiddleWare.setTrustManagers(wrappedTrustManagers);
            sslMiddleWare.setHostnameVerifier(newHostnameVerifier() {
                publicbooleanverify(String hostname, SSLSession session) {
                    returntrue;
                }
            });
            sslMiddleWare.setSSLContext(sslContext);

            Ion.with(this)
                    .load("https://yoururl")
                    .setBodyParameter("key1", "value1")
                    .setBodyParameter("key2", "value2")
                    .asString()
                    .setCallback(newFutureCallback<String>() {
                        @OverridepublicvoidonCompleted(Exception e, String result) {
                            if (result != null)
                                Log.d("responsearrived", result);

                            if (e != null) Log.d("responserror", e.toString());
                        }
                    });
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

This is more dangerous, and should be used for testing purposes only... But this works, without adding certificates to the filesystem... You mentioned that your project is in development phase, so this should help you, for now...

Post a Comment for "How To Use Self-signed Ssl In Android Network Library (ion)?"