Securing Server Interactions


Securing server communications:

       The android uses the standard way of communication (HTTPS) connection using the HttpsURLConnection  class

HttpsURLConnection urlConn = new HttpsURLConnection("https://
          clientaccess.example.com");
Once the connection has been made you can check the connection using the
getServerCertificates() which gives you the server certificate with the server name and other stuff. If the server certificates don’t match with the server connected, it brings out an exception and terminates that connection. The hostname verification can be done with 3 different interfaces.

AllowAllHostnameVerifier


                 This hostname verifier turns hostname verification off. As long as the certificate that is presented by the server is trusted comes from a trusted Certificate Authority . It just accepts regardless of the hostname and the URL match.

StrictHostnameVerifier


This hostname verifier is the same as the verification in the default. It checks the first CN present in the server certificate against the hostname specified in the URL and also checks all of the subject entries in the certificate for a match. Wildcards are allowed, but only up to one level. For example,*.example.com would match server1.example.com, but not server1.domain1.example.com.

BrowserCompatHostnameVerifier


                               This hostname verifier is just like StrictHostnameVerifier, but wildcards in the certificate name will match multiple levels. It accepts server1.domain1.example.com if you specify *.example.com.
In the above three verifications StrictHostnameVerifier has the more secure interaction with the server

HostnameVerifier newHV = new StrictHostnameVerifier();
HttpsURLConnection.setDefaultHostnameVerifier(newHV);
We can also verify and limit the server certificates by creating our own HostNameVerifier class and allow only few certificates that we need to allow.


Private client server communications:


Client side authentication

    
     To have a private client server communications we ourselves generate a self signed certificate in the server which will be valid for one year and it will be stored in the certsjks in JKS format. We cannot use it directly in our android application so we need to convert it onto a BKS key store.Once the certificate is been produced we need to access in our application for the secure authentication. We use key store object to do it.

Key store for creating the server certificate.


KeyStore selfsignedKeys = KeyStore.getInstance("BKS");
selfsignedKeys.load(context.getResources().openRawResource(R.raw.selfsignedcertsbks),
"genericPassword".toCharArray());

When the key store loads the server certificate we call the trust manager to check it.

TrustManagerFactory trustMgr =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustMgr.init(selfsignedKeys);

The trust manager factory object will verify the self signed certificate.
Once we have the Trust Manager Factory, we can create the SSLContext that we will need to make SSL/TLS connections using our certificate.

SSLContext selfsignedSSLcontext = SSLContext.getInstance("TLS");
selfsignedSSLcontext.init(null, trustMgr.getTrustManagers(), new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(selfsignedSSLcontext.getSocketFactory());

Then we call the init () with 3 parameters. The client side keys, trust manager factory and the secure random.

 

Server- Side authentications:

         The client will verify the server that it logs in but the server does not check to which client it communicates. When we work in a controlled environment the server needs to make sure it communicates with the correct device.

To do this we need to create a client certificate for the server to validate it and conform that it is communicating to the correct device. This should be done in the web server. The client certificate will be stored in the clientauthcertsBKS store .we have two key stones for the client and the server, so we now create a authenticated secure SSL/TLS connections.

Key store for the client certificate. The code remains the same but instead of trust manager we use key manager which sends the client certificate to the server for the client side authentication. 

KeyStore clientauthKeys = KeyStore.getInstance("BKS");
clientauthKeys.load(context.getResources().openRawResource(R.raw.clientauthcertsbks),"genericPassword".toCharArray());
KeyManagerFactory   KeyMgr=KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyMgr.init(clientauthKeys, "genericPassword".toCharArray());

Then we create a key manager factory similar to the trust manager factory to generate the key manager which holds up the client certificates.

Next we will create a SSLContext for the same as we did for the server authentication.

SSLContext privateSSLcontext = SSLContext.getInstance("TLS");
privateSSLcontext.init(keyMgr.getKeyManagers(), trustMgr.getTrustManagers(),
new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(privateSSLcontext.getSocketFactory());

Once you have done with the SSL Context we have to call the init() with the 3 parameters
We use key manager as the first parameter  , trust manager and then the secure Random function.
We now have an SSL/TLS configuration that restricts which server certificates
we will accept and includes client certificates that we can use to identify ourselves to those servers. By making use of these constructs, we can fully specify how we want our SSL/TLS communications to act for our application. The ability to specify both who we are willing to talk to and to whom we will identify ourselves allows the creation of private, secure communication tunnels that are both mutually authenticated and encrypted.


No comments:

Post a Comment

 

Contributors

Social Connect


View Sadagopan K V's profile on LinkedIn