Android: Import SSL certificate and use it to SSL connection


  1. First of all you need get SSL certificate. You can obtain certificate (file with .cer extention) from the chain included in the endpoint certificate or from the official site of the issuer (in the Base64 encoded X.509 format).

    Or if you have this certificate installed on you local computer you can obtain it by run "mmc" (Microsoft Management Console) from command line ("Prompt" or "Run"). If you don't have Certificate snap-in go to  File -> Add/Remove Snap-in... -> Select from available snap-ins "Certificates" -> Add to Selected snap-ins -> Ok.

    Find certificate what do you need -> Right click -> All Tasks -> Export -> Select Base-64 encoded X.509 (.CER) -> Save into my_certificate.cer in my_certificate_path place.

    Content of this file look like:
    -----BEGIN CERTIFICATE-----
    MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0B...
    -----END CERTIFICATE-----
    
  2. For create the keystore download latest release of Bouncy Castle provider (bcprov-jdkxx-xxx.jar) and store it in provider_path place. You must have JRE installation for invoke keytool (located under bin folder). You may add path to keytool into CLASSPATH environment variable or use absolute path.
  3. Execute this command for create mykeystore.bks (don't use upper case and "_" for name):
    D:/PROGRA~1/Java/jre7/bin/keytool -importcert -v -trustcacerts -file "my_certificate_pathmy_certificate.cer" -alias myAlias -keystore "my_keystore_path/mykeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "provider_path/bcprov-jdkxx-xxx.jar" -storetype BKS -storepass "my_password"
    
  4. You may verify if the certificate was imported correctly
    D:/PROGRA~1/Java/jre7/bin/keytool -list -keystore "my_keystore_path/mykeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "provider_path/bcprov-jdkxx-xxx.jar" -storetype BKS -storepass "my_password"
    
  5. Paste you mykeystore.bks as a raw resource under res/raw (this generate R.raw.mykeystore resource)
  6. Create a custom HttpClient to use you SSL certificate for HTTPS connection:
    import java.io.InputStream;
    import java.security.KeyStore;
    
    import org.apache.http.conn.ClientConnectionManager;
    import org.apache.http.conn.scheme.PlainSocketFactory;
    import org.apache.http.conn.scheme.Scheme;
    import org.apache.http.conn.scheme.SchemeRegistry;
    import org.apache.http.conn.ssl.SSLSocketFactory;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.impl.conn.SingleClientConnManager;
    
    import android.content.Context;
    
    public class MyHttpsClient extends DefaultHttpClient {
      
        final Context context;
     
        public MyHttpsClient(Context context) {
            this.context = context;
        }
     
        @Override
        protected ClientConnectionManager createClientConnectionManager() {
            SchemeRegistry registry = new SchemeRegistry();
            registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
            // Register for port 443 our SSLSocketFactory with our keystore
            // to the ConnectionManager
            registry.register(new Scheme("https", newSslSocketFactory(), 443));
            return new SingleClientConnManager(getParams(), registry);
        }
     
        private SSLSocketFactory newSslSocketFactory() {
            try {
                // Get an instance of the Bouncy Castle KeyStore format
                KeyStore trusted = KeyStore.getInstance("BKS");
                // Get the raw resource, which contains the keystore with
                // your trusted certificates (root and any intermediate certs)
                InputStream in = context.getResources().openRawResource(R.raw.mykeystore);
                try {
                    // Initialize the keystore with the provided trusted certificates
                    // Also provide the password of the keystore
                    trusted.load(in, "my_password".toCharArray());
                } finally {
                    in.close();
                }
                // Pass the keystore to the SSLSocketFactory. The factory is responsible
                // for the verification of the server certificate.
                SSLSocketFactory sf = new SSLSocketFactory(trusted);
                // Hostname verification from certificate
                // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506
                sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
                return sf;
            } catch (Exception e) {
                throw new AssertionError(e);
            }
        }
    }
    
  7. Use you custom HttpClient:
    DefaultHttpClient client = new MyHttpsClient(getApplicationContext());