The aim of this blog is to set up a secure connection between an Android device and a Tomcat instance so that both can exchange information over an encrypted channel.
The first step is generating a server certificate to be used in Tomcat. For the purposes of this post the certificate will be self-signed, but in production environments you would typically use a certificate signed by some certificate authority such as Verisign.
keytool -genkeypair -alias tomcat -keyalg RSA -keysize 1024 -dname "CN=localhost, OU=Organization, O=Company Name, L=City, S=State, C=US" -validity 365 -storepass password
On Linux this would generate a keystore under your home directory named “.keystore”.
After generating the certificate you have to edit Tomcat’s server.xml configuration file to handle secure connections. The default port is 8443. In /usr/share/tomcat6/conf you should have a section similar to this which is commented:
Uncomment the section and add attributes to refer to your keystore and keystore password as shown below:
After setting this up and restarting Tomcat you should be able to access your web application by pointing your browser to https://server-ip:8443/webapp (Replace server-ip and webapp with your server’s IP address and webapp name)
When working with HTTP using Android, a commonly used library is the Apache HttpClient library. After switching the server to TLS you will get an SSLPeerUnverifiedException due to the client not trusting the self-signed certificate configured on the server. To address this you can extend the DefaultHttpClient and set it up so that the trust store it uses is aware of the self-signed certificate.
First you need to export your certificate in a format which is compatible with Android. We will use the Bouncy Castle keystore format as Android has built-in support for it.
keytool -export -alias tomcat -file keystore.cer -storepass password
After getting the certificate in the keystore.cer file use keytool to convert it to the bouncy castle format. (Replace $PATH_TO_BC with the path to the bouncy castle jar)
keytool -import -alias tomcat -file keystore.cer -keypass password -keystore keystore.bks -storetype BKS -storepass password -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath $PATH_TO_BC/bcprov-jdk16-1.46.jar
Once you have the certificate in bks format you should store it under the android /res/raw/keystore.bks folder allowing you to access it using R.raw.keystore. Next override the createClientConnectionManager() method so that it loads the certificate into the trust store as shown below:
Finally change your android client code so that it uses your ‘freshly baked’ CustomHttpClient instead of DefaultHttpClient!