Wednesday, September 8, 2010

Step-to-Step Guide to Programming Android SSL with Self-Signed Server Certificate

There is a dearth of SDK documentation on how to work with SSL connections on Android with self-signed certificate. Here is a method that stores a self-signed certificate in the application resource and then later uses that certificate for SSL connections.

1. We create a self-signed server certificate for our SSL server:
keytool -genkey -dname "cn=ssltest, ou=test, o=example, c=US" 
   -alias ssltest -keypass ssltest -keystore c:\test\ssltest.keystore 
   -storepass ssltest -validity 180

2. We export the certificate to a file:
keytool -export -alias ssltest -keystore c:\test\ssltest.keystore 
   -file c:\test\ssltest.cer -storepass ssltest -keypass ssltest

3. Since Android uses the JCE provider from Bouncy Castle, we download the provider jar bcprov-jdk16-145.jar from BC and store it at C:\androidproject\libs.

4. Now, we import the server certificate to our Android project as a raw resource:
keytool -import -alias ssltestcert -file C:\test\ssltest.cer 
   -keypass ssltestcert -keystore C:\androidproject\res\raw\ssltestcert 
   -storetype BKS -storepass ssltestcert 
   -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider 
   -providerpath c:\androidproject\libs\bcprov-jdk16-145.jar
Note that we give it a store type BKS.
If you use the Eclipse ADK, the ADK will automatically create a resource id ssltestcert after you refresh the project.

5. We can now use the server certificate in our Java program:
// Load the self-signed server certificate
char[] passphrase = "ssltestcert".toCharArray();
KeyStore ksTrust = KeyStore.getInstance("BKS");
ksTrust.load(context.getResources().openRawResource(R.raw.ssltestcert),
             passphrase);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
tmf.init(ksTrust);

// Create a SSLContext with the certificate
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), new SecureRandom());

// Create a HTTPS connection
URL url = new URL("https", "10.0.2.2", 8443, "/ssltest");
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();

/* Uncomment the following line of code if you want to skip SSL */
/* hostname verification.  But it should only be done for testing. */
/* See http://randomizedsort.blogspot.com/2010/09/programmatically-disabling-java-ssl.html */
/* conn.setHostnameVerifier(new NullVerifier()); */

conn.setSSLSocketFactory(sslContext.getSocketFactory());

Congratulations! You can now use your self-signed server certificate for SSL communication.

14 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. Had to adjust a little, but worked well. Thanks for the post

    ReplyDelete
  3. Hi,
    Could you share what adjustments were needed?

    ReplyDelete
  4. Hi,
    I followed the steps mentioned above to generate the BKS keystore and am able to open it using Portecle.
    However, when i run the app, the server throws an exception at the accept call "could not find any key store entries to support the enabled cipher suites"
    Are any changes needed to the client code as well?

    ReplyDelete
    Replies
    1. client code? I didn't make any changes to the server code. I already had a self signed ssl certificate. Once you have those you don't really need to do much with those. Other then plug it in to what ever server setup you're using. Mine personally was a Node.js application.

      I used something like present in this: http://www.akadia.com/services/ssh_test_certificate.html through step 4.

      Since I had already generated my self signed ssl certs.

      Then used step 4 on this post to generate the keystore.

      While the info here is useful. It could have been structured better. For sure would have helped to have some of the commands explained.

      Delete
    2. https://gist.github.com/AaronOgle/5527063

      Here's my server communication file, with the ssl stuff working. As well as showing it used.

      Hope that helps.

      Delete
    3. Hi,
      Thanks for responding.
      Could you share more details on the process of generating self signed certificates?
      Like i said before, i get an exception "could not find trusted keystore for enabled cipher suites" when the server invokes the accept system call.

      Thanks

      Delete
    4. Like I said I generated it using the method described here: http://www.akadia.com/services/ssh_test_certificate.html

      or

      here: http://blog.didierstevens.com/2008/12/30/howto-make-your-own-cert-with-openssl/

      openssl genrsa -out host.key 4096

      openssl req -new -x509 -days 1826 -key host.key -out host.crt

      fill out the info it asks for.

      Then follow the steps here starting with step 4.

      keytool -import -alias ssltestcert -file host.crt
      -keypass ssltestcert -keystore C:\androidproject\res\raw\keystore
      -storetype BKS -storepass somepassword
      -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider
      -providerpath c:\androidproject\libs\bcprov-jdk16-145.jar

      Might take some tweaking. But such is the nature of programming.

      Good luck

      Delete
    5. Thanks for the reply Aaron. :-)

      Delete
  5. This comment has been removed by the author.

    ReplyDelete
  6. Considerably, the particular post is truly the greatest with this deserving subject. To be sure together with your results and also can easily thirstily look forward to Your own potential improvements. Simply just declaring thank you will, no doubt not simply just be sufficient, for your wonderful quality within your writing. I will immediately grab your rss to remain up to date with any kind of updates. Real perform as well as much success inside your company dealings! website tips

    ReplyDelete
  7. Very best people messages are meant to charm allow honor toward groom and bride. Newbie speakers in front of excessive locations should usually our own gold colored dominate in presenting and public speaking, which is to be personal interests home. best man speach converting websites

    ReplyDelete
  8. Hire UI Developer Freelancer (Subject matter expert) & get online UI Developer job support from 1 hour to 1-year contract assignment. Get UI Developer job support in projects on time, within budget, with a high level of quality, and meet the customer’s current & future challenges. Outsource UI Developer project and our exclusive SME work closely with your business to ensure you get the most out of your IT solutions, offering system implementation solutions, resources, and training. UI Developer Support

    ReplyDelete
  9. Regular SSL provide security to both the website owners as well as users. Any site owner that needs to use a customer's personal data will require these certificates. This article discusses the importance of these certificates and how to choose them.

    ReplyDelete