It’s very common when building enterprise Android apps to have a Web service connection. It’s a great mechanism for synchronizing data with the server-side of an application. There are two fundamental styles of Web service in use: REST (Representation State Transfer) and SOAP (which allegedly stands for Simple Object Access Protocol). Whichever style of service you use, there is a pretty high chance that you do not want to share your Web service data with snoopers!
In the World of SOAP services, there are some complex protocols which allow the body of the SOAP message to be encrypted. REST has not such mechanism. Fortunately, there is a simple and highly effective solution to securing both types of Web service. Normally, Web service communication takes place over HTTP the ubiquitous protocol of the Web. HTTP sends all data as plain text so unless you have pre-encrypted it, anyone when with access to your communication channels can intercept the data. The solution is to use HTTPS which is the HTTP protocol run over and encrypted transport layer (TLS or Transport Level Security (earlier versions of TLS are known as SSL)).
In principle at least, it is really easy to switch your services to use HTTPS: just change the endpoint URL to use the HTTPS protocol identifier. E.g. https://myservice.com/service. It’s actually a little more complicated in that the client side needs to trust the Web service. Trust is established via digital certificates (typically X.509) which contain encryption keys and are signed by a trusted certificate authority. In Android, establishing this trust means making sure that the certificate of the Web server hosting the service is installed in the keychain. If you don’t do this, you will get a SSLPeerUnverifiedException which is the message from the TLS implementation indicating that it can’t find a certificate belonging to the server in it’s keychain.
To import the server HTTPS certificate, you need to have it in DER format with a .crt extension or Android won’t recognize it. You then need to push it onto the Android device:
adb shell push servercert.crt /mnt/sdcard
Once it is on the SD card: on the Android device, go to System Settings | Security | Credentials |Install from SD Card. Android will then prompt you for which certificate to install. Once the installation is complete, the original certificate file is deleted from the SD card. If you are working in the emulator and using a server running on your local host then you will need a certificate with a common name of 10.0.2.2 which is the IP address used to access localhost from within the emulator. You will probably want to generate that certificate yourself using a tool such as openssl.
I’ve put a script for generating certifcates and keys using openssl onto Github . It’s intended primarily as a reference to the commands you need. They are all commented and the individual should run fine on a Windows box with openssl installed. If you are in a *nix environment and want to use it directly then create a directory somewhere with a sub-directory of private copy the script into that directory. Install the openssl configuration file in the directory above the one with the script in it. When you run the script, it actually generates two sets of server certificates one for 10.0.2.2 and another for localhost.
If you have generated your own certificate using commands lie the ones in my script then there is one task left to perform: you must import the certificate authority certificate into Android. You actually do that using exactly the same process as for the server certificate.
Once you have all this in place, you should be good to go. Get your service up and running on the server with HTTPS enabled and then change the endpoint in your Web service client to use HTTPS. If it’s not working then LogCat will give you some pretty explicit clues as to the problem!
Learning Tree cover this and a whole load of really interesting security stuff in their Mobile Device and Application Security Course.