Using Android Volley With Self-Signed SSL Certificate

Posted / Публикувана 2013-05-28 in category / в категория: Android

In brief:

  1. Get Volley from git clone https://android.googlesource.com/platform/frameworks/volley
  2. Get Android Volley Examples project from git clone git://github.com/ogrebgr/android_volley_examples.git
  3. Copy your keystore (BKS format) containing the self-signed public key in res/raw
  4. Open Act_SsSslHttpClient in the examples project, find "R.raw.test" and replace it with your keystore name (without the .pem extension)
  5. Find "new SslHttpClient(" and replace the default password "test123″ with the password for your keystore
  6. Replace "44400″ with the HTTPS port of your server/virtualhost. If you use the standart 443 -- then you may remove this parameter entirely
  7. Replace "https://tp.bolyartech.com:44400/https_test.html" with your  URL. Please make sure that you are using HTTPS otherwise it will work without as normal request, i.e. without encryption
  8. Start the app, go to "HTTPS with self-signed cert", then "Execute HTTPS request"
  9. If successful you will see something like "This is the result of successful HTTPS request. Congrats!". If some error occurres please check your logcat.
  10. Copy SslHttpClientSslSocketFactorySsX509TrustManager and your keystore to your project and enjoy! :-)

 

In details:

When you create an android app there is  no problem to execute HTTPS request against server with certificate issued by well-known Certification authority. However if you try to you use self-signed certificate you are in trouble -- certificate will be rejected by the trust manager because it cannot be traced to trusted root. Put simply: your certificate does not match any of the built-in (in android) certificates. The solution that I came with is to use external (and newer) HttpClient and provide my own TrustManager that has my self-signed certificate added in.

Few weeks ago, Volley came out. In my previous posting I demonstrated how to use an external HttpClient. Now I will build on that and provide description and example how to use Volley with self-signed certificate.

What will you need:

  • Volley Framework. You can get it using: git clone https://android.googlesource.com/platform/frameworks/volley
  • Volley Android Examples (aka examples). git clone git://github.com/ogrebgr/android_volley_examples.git
  • Your webserver/virtualhost setup with your self-signed certificate
  • the public key of the self-signed certificate (will be explained bellow)

I will assume that you will have Volley and the examples  installed and running. I will assume that you have your server/virtualhost configured to use self-signed certificate (If you need info how to achieve that: this article may help).

1. Preparing your BKS keystore

Android uses keystores in BKS (Bouncy Castle) format. When you generated your certificate it is in PEM format so you will need to import it into a new BKS keystores. Some tutorials that show how to generate your certificate use one and the same file for the private and public keys. You need a file that contains only the public key, i.e. the content starting from "-----BEGIN CERTIFICATE-----" and ending with "-----END CERTIFICATE-----" (inclusive).  If your certificate contains other rows please copy it with new name like my_server_cert.crt and remove those rows. Please note that the result must be plain text file, i.e. don't use fancy editors that may convert it to UTF-8  for example.

In order to create a BKS keystore you will need so called provider jar bcprov-jdk16-146.jar. Please note that you need to use this version. Newer versions will not work with Android (or at least with older versions before 4.1).

Use this command to import your cert into new BKS keystore:

keytool -importcert -v -trustcacerts -file "my_server_cert.crt" -alias imeto_alias -keystore "my.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "bcprov-jdk16-146.jar" -storetype BKS

where my_server_cert.crt is your apache certificate and  my.bks is the name of resulting BKS keystore file. Above command assumes that both my_server_cert.crt and bcprov-jdk16-146.jar are in the current directory.

You will be asked to choose some password.

2. Put the BKS keystore in the project

Put my.bks into the example project in directory res/raw.

Follow the steps from "In brief" section above starting from 4.

 

If you need to use self-signed certificates in your own projects you will need following classes SslHttpClientSslSocketFactorySsX509TrustManager. You will need also ExtHttpClientStack if you are not using it yet.

As always any comments, criticism and bug reports will be highly appreciated. :-)

 

 

9 Responses to “Using Android Volley With Self-Signed SSL Certificate”

  1. Peter Hilbring Says:

    Do you have any example about using client ssl authentification with volley?

  2. Ogi Bankov / Огнян Банков Says:

    I am afraid that I don't but it should not be hard to do it:
    There is a description how to do it in principle http://developer.android.com/reference/javax/net/ssl/HttpsURLConnection.html (Providing an application specific X509KeyManager)

    Basically all you have to do is to load your client certificate into KeyManager and then pass that manager to the sslcontext.init( as first parameter (SslSocketFactory, line 39)

    Please note that self-signed certificate will not work as client certificate if server is not configured to accept it (which is the default).

  3. Peter Hilbring Says:

    Thanks for your response. I'll try that in the next days.

  4. Michael Says:

    Thanks Ognyan.

    I'm somehow stuck with a

    javax.net.SSLPeerUnverifiedExeption: No peer certificate.

    Any idea what's wrong? (I'm using lighttpd)

  5. Hélio Padrão Says:

    It worked, congratulations.

  6. Vacharaphol Says:

    Hi! Ognyan

    I got an error \"com.android.volley.NoConnectionError: javax.net.ssl.SSLPeerUnverifiedException: No peer certificate\" after using Volley.newRequestQueue(getApplicationContext(), new ExtHttpClientStack(new SslHttpClient(keyStore, \"android\", 443))) call to \"https://www.maywebsite.com:443/abcd/login.php\"

    Do you have any suggestion?

  7. Ogi Bankov / Огнян Банков Says:

    @Vacharaphol
    Are you using self-signed certificate?
    Probably it will the best to post the question on http://stackoverflow.com along with more info (like code snippet, type of the certificate, etc). That way more people will see it and will be able to help.

  8. Vacharaphol Says:

    Thanks

  9. Vacharaphol Says:

    I think my problem may come from Apache Virtual Host. I try to get public key using openssl like this "openssl s_client -connect http://www.mywebsite.com:443/abcd/login.php>myweb.pem" and I got another public key.

    Do you have any solution to solve this problem?

Leave a Reply

Notify me of followup comments via e-mail. You can also subscribe without commenting.

Security Code: