Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The following main steps are required to achieve a secured connection from Certification Authorities which are not considered as trusted by the android platform.</p> <p>As requested by many users, I've mirrored the most important parts from my <a href="http://blog.antoine.li/index.php/2010/10/android-trusting-ssl-certificates/" rel="noreferrer">blog article</a> here:</p> <ol> <li>Grab all required certificates (root and any intermediate CA’s)</li> <li>Create a keystore with keytool and the <a href="http://www.bouncycastle.org/" rel="noreferrer">BouncyCastle</a> provider and import the certs</li> <li>Load the keystore in your android app and use it for the secured connections (I recommend to use the <a href="http://hc.apache.org/httpcomponents-client-ga/index.html" rel="noreferrer">Apache HttpClient</a> instead of the standard <code>java.net.ssl.HttpsURLConnection</code> (easier to understand, more performant)</li> </ol> <h2>Grab the certs</h2> <p>You have to obtain all certificates that build a chain from the endpoint certificate the whole way up to the Root CA. This means, any (if present) Intermediate CA certs and also the Root CA cert. You don’t need to obtain the endpoint certificate.</p> <h2>Create the keystore</h2> <p>Download the <a href="http://bouncycastle.org/download/bcprov-jdk16-145.jar" rel="noreferrer">BouncyCastle Provider</a> and store it to a known location. Also ensure that you can invoke the keytool command (usually located under the bin folder of your JRE installation).</p> <p>Now import the obtained certs (don’t import the endpoint cert) into a BouncyCastle formatted keystore.</p> <p>I didn’t tested it, but I think the order of importing the certificates is important. This means, import the lowermost Intermediate CA certificate first and then all the way up to the Root CA certificate.</p> <p>With the following command a new keystore (if not already present) with the password <em>mysecret</em> will be created and the Intermediate CA certificate will be imported. I also defined the BouncyCastle provider, where it can be found on my file system and the keystore format. Execute this command for each certificate in the chain.</p> <pre><code>keytool -importcert -v -trustcacerts -file "path_to_cert/interm_ca.cer" -alias IntermediateCA -keystore "res/raw/myKeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret </code></pre> <p>Verify if the certificates were imported correctly into the keystore:</p> <pre><code>keytool -list -keystore "res/raw/myKeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret </code></pre> <p>Should output the whole chain:</p> <pre><code>RootCA, 22.10.2010, trustedCertEntry, Thumbprint (MD5): 24:77:D9:A8:91:D1:3B:FA:88:2D:C2:FF:F8:CD:33:93 IntermediateCA, 22.10.2010, trustedCertEntry, Thumbprint (MD5): 98:0F:C3:F8:39:F7:D8:05:07:02:0D:E3:14:5B:29:43 </code></pre> <p>Now you can copy the keystore as a raw resource in your android app under <code>res/raw/</code></p> <h2>Use the keystore in your app</h2> <p>First of all we have to create a custom Apache HttpClient that uses our keystore for HTTPS connections:</p> <pre><code>public class MyHttpClient extends DefaultHttpClient { final Context context; public MyHttpClient(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, "mysecret".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); } } } </code></pre> <p>We have created our custom HttpClient, now we can just use it for secure connections. For example when we make a GET call to a REST resource.</p> <pre><code>// Instantiate the custom HttpClient DefaultHttpClient client = new MyHttpClient(getApplicationContext()); HttpGet get = new HttpGet("https://www.mydomain.ch/rest/contacts/23"); // Execute the GET call and obtain the response HttpResponse getResponse = client.execute(get); HttpEntity responseEntity = getResponse.getEntity(); </code></pre> <p>That's it ;)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload