Android supports certificates in the BKS, P12 and other formats.
For BKS format:
Use portecle to convert your certificates (.p12 and .crt) to .bks.
You need 2 files in your /res/raw
folder:
truststore.bks
trust certificate for the server (converted from .cer file)
client.bks/client.p12
– the client certificate (converted from a .p12 file that contains the client certificate and the client key)
import java.io.*;
import java.security.KeyStore;
import javax.net.ssl.*;
import org.apache.http.*;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.*;
import org.apache.http.conn.scheme.*;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.*;
import android.app.Activity;
import android.os.Bundle;
public class SslTestActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
// setup truststore to provide trust for the server certificate
// load truststore certificate
InputStream clientTruststoreIs = getResources().openRawResource(R.raw.truststore);
KeyStore trustStore = null;
trustStore = KeyStore.getInstance("BKS");
trustStore.load(clientTruststoreIs, "MyPassword".toCharArray());
System.out.println("Loaded server certificates: " + trustStore.size());
// initialize trust manager factory with the read truststore
TrustManagerFactory trustManagerFactory = null;
trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
// setup client certificate
// load client certificate
InputStream keyStoreStream = getResources().openRawResource(R.raw.client);
KeyStore keyStore = null;
keyStore = KeyStore.getInstance("BKS");
keyStore.load(keyStoreStream, "MyPassword".toCharArray());
System.out.println("Loaded client certificates: " + keyStore.size());
// initialize key manager factory with the read client certificate
KeyManagerFactory keyManagerFactory = null;
keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, "MyPassword".toCharArray());
// initialize SSLSocketFactory to use the certificates
SSLSocketFactory socketFactory = null;
socketFactory = new SSLSocketFactory(SSLSocketFactory.TLS, keyStore, "MyTestPassword2010",
trustStore, null, null);
// Set basic data
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, "UTF-8");
HttpProtocolParams.setUseExpectContinue(params, true);
HttpProtocolParams.setUserAgent(params, "Android app/1.0.0");
// Make pool
ConnPerRoute connPerRoute = new ConnPerRouteBean(12);
ConnManagerParams.setMaxConnectionsPerRoute(params, connPerRoute);
ConnManagerParams.setMaxTotalConnections(params, 20);
// Set timeout
HttpConnectionParams.setStaleCheckingEnabled(params, false);
HttpConnectionParams.setConnectionTimeout(params, 20 * 1000);
HttpConnectionParams.setSoTimeout(params, 20 * 1000);
HttpConnectionParams.setSocketBufferSize(params, 8192);
// Some client params
HttpClientParams.setRedirecting(params, false);
// Register http/s shemas!
SchemeRegistry schReg = new SchemeRegistry();
schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schReg.register(new Scheme("https", socketFactory, 443));
ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg);
DefaultHttpClient sClient = new DefaultHttpClient(conMgr, params);
HttpGet httpGet = new HttpGet("https://server/path/service.wsdl");
HttpResponse response = sClient.execute(httpGet);
HttpEntity httpEntity = response.getEntity();
InputStream is = httpEntity.getContent();
BufferedReader read = new BufferedReader(new InputStreamReader(is));
String query = null;
while ((query = read.readLine()) != null)
System.out.println(query);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Update:
You can also load .crt files for the trust store directly without converting them to BKS:
private static KeyStore loadTrustStore(String[] certificateFilenames) {
AssetManager assetsManager = GirdersApp.getInstance().getAssets();
int length = certificateFilenames.length;
List<Certificate> certificates = new ArrayList<Certificate>(length);
for (String certificateFilename : certificateFilenames) {
InputStream is;
try {
is = assetsManager.open(certificateFilename, AssetManager.ACCESS_BUFFER);
Certificate certificate = KeyStoreManager.loadX509Certificate(is);
certificates.add(certificate);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Certificate[] certificatesArray = certificates.toArray(new Certificate[certificates.size()]);
return new generateKeystore(certificatesArray);
}
/**
* Generates keystore congaing the specified certificates.
*
* @param certificates certificates to add in keystore
* @return keystore with the specified certificates
* @throws KeyStoreException if keystore can not be generated.
*/
public KeyStore generateKeystore(Certificate[] certificates) throws RuntimeException {
// construct empty keystore
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
// initialize keystore
keyStore.load(null, null);
// load certificates into keystore
int length = certificates.length;
for (int i = 0; i < length; i++) {
Certificate certificate = certificates[i];
keyStore.setEntry(String.valueOf(i), new KeyStore.TrustedCertificateEntry(certificate),
null);
}
return keyStore;
}
Same goes for the KeyStore with the client certificate, you can use the .p12 file directly without converting it to BKS.