Testing Android to App Engine over HTTPS in Local Development

PreethumWed, 2015-04-01 00:10

In working with the GWT-SyncProxy project, I needed perform testing over the HTTPS protocol. Since Google App Engine is the server choice for my testing base, I had to look across articles all over the place to find a way to provide for a simple test of an RPC over HTTPS from a testing Android device. This article will detail how to set this up using STunnel (https://www.stunnel.org/downloads.html).

Code assumptions (these values may vary depending on your setup):

  • GAE Local Hosted mode is sitting at 127.0.0.1:8888
  • The computer hosting GAE has an IP Address of 192.168.2.20 on your local network
    • Your Android Device and Hosting computer are connected to the same network

Step 1: Install and Configure STunnel

Follow the basic install settings for  STunnel. During the installation, STunnel will prompt you to create the Self-Signed SSL certificate that will be used to make this work. If you are planning on testing with the Android Emulator, use the localhost value for Common Name (CN) when prompted. If you plan on using a real device, use the computer's IP Address instead for the CN. If you misconfigure this value, you may end up with a couple unexpected errors (1).

In the stunnel config, uncomment the following to enable legacy mode (working on updating for proper use, but this works well enough for locally testing):

options = -NO_SSLv3 

Then add the following section to act as the tunnel to your local dev server (9):

[inhouse-dev]
accept = (ip.address.of.machine):8080
connect = 8888

Step 2: Create certificate for Android Keystore

STunnel installation will have created a ".pem" file. Locate this file in the installation directory, open it up. Once the .pem file is created, open it up and copy items between (and including) --------BEGIN CERTIFICATE-------- and -------END CERTIFICATE-------- to a new file, say "cert.pem"(2). Then from the command line, run the follow keytools command (3, 4, 5) :

keytool -import -file cert.pem -alias server -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath bcprov-jdk15on-146.jar -keystore server.bks -v -trustcacerts

This process will request you to create a password. Be sure to keep track of it (see BKSPASS in the code sample below). The bouncycastle jar is available here: http://www.bouncycastle.org/download/bcprov-jdk15on-146.jar.

Step 3: Install Keystore into HTTPS Connections

Remove extension from server.bks, then add it to the raw resource folder for your android project. Use the following template to create the KeyStore for Android (6):

KeyStore localTrustStore = KeyStore.getInstance("BKS");
InputStream in = getResources().openRawResource(R.raw.server);
localTrustStore.load(in, "BKSPASS".toCharArray());

TrustManagerFactory tmf = TrustManagerFactory
    .getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(localTrustStore);

SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, tmf.getTrustManagers(), null);
sslFactory = ctx.getSocketFactory();

Then use the following code sample to install and use this sslFactory into your connections:

HttpsURLConnection.setDefaultHostnameVerifier(
    new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    });
HttpsURLConnection.setDefaultSSLSocketFactory(sslFactory);

Sources:

1. http://stackoverflow.com/a/26738760/1544046
2. http://stackoverflow.com/questions/9889669/error-importing-ssl-certificate-not-an-x-509-certificate
3. http://stackoverflow.com/questions/859111/how-do-i-accept-a-self-signed-certificate-with-a-java-httpsurlconnection
4. http://stackoverflow.com/questions/6933103/wrong-version-keystore-when-doing-https-call
5. http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html
6. http://stackoverflow.com/a/13925635/1544046
7. http://stackoverflow.com/a/859271/1544046
8. http://stackoverflow.com/a/15252178/1544046
9. http://stackoverflow.com/questions/7741903/google-app-engine-need-to-use-ssl-on-localhost-to-develop-canvas-app

Blog Category: