How to use p12 certificates in Android (client certificates)

I am trying to use client certificates in android. I received a .p12 file that I want to use for authentication on the server.

I use portecle to convert a .p12 file to a .bks file, but I don't seem to get it working.

Here is the code:

package com.pa1406.SECURE; import java.io.InputStream; import java.security.KeyStore; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.TrustManagerFactory; 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 HttpsClient extends DefaultHttpClient { final Context context; public HttpsClient(Context context) { this.context = context; } @Override protected ClientConnectionManager createClientConnectionManager() { SchemeRegistry registry = new SchemeRegistry(); registry.register( new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); registry.register( new Scheme("https",newSslSocketFactory(), 443)); return new SingleClientConnManager(getParams(), registry); } private SSLSocketFactory newSslSocketFactory() { try { KeyStore truststore = KeyStore.getInstance("BKS"); InputStream in = context.getResources().openRawResource(R.raw.keystore); try { truststore.load(in, "qwerty1234".toCharArray()); } finally { in.close(); } return new SSLSocketFactory(truststore); } catch (Exception e) { throw new AssertionError(e); } } } 

What can I do for this?

UPDATE:

 package com.pa1406.SECURE; import java.io.InputStream; import java.security.KeyStore; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; 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 HttpsClient extends DefaultHttpClient { final Context context; public HttpsClient(Context context) { this.context = context; } @Override protected ClientConnectionManager createClientConnectionManager() { SchemeRegistry registry = new SchemeRegistry(); registry.register( new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); registry.register( new Scheme("https",newSslSocketFactory(), 443)); return new SingleClientConnManager(getParams(), registry); } private SSLSocketFactory newSslSocketFactory() { try { // setup truststore to provide trust for the server certificate // load truststore certificate InputStream clientTruststoreIs = context.getResources().openRawResource(R.raw.truststore); KeyStore trustStore = null; trustStore = KeyStore.getInstance("BKS"); trustStore.load(clientTruststoreIs, "qwerty1234".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 = context.getResources().openRawResource(R.raw.torbix); KeyStore keyStore = null; keyStore = KeyStore.getInstance("BKS"); keyStore.load(keyStoreStream, "qwerty1234".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, "qwerty1234".toCharArray()); // initialize SSLSocketFactory to use the certificates SSLSocketFactory socketFactory = null; socketFactory = new SSLSocketFactory(SSLSocketFactory.TLS, keyStore, "qwerty1234", trustStore, null, null); return socketFactory; } catch (Exception e) { throw new AssertionError(e); } } } 
+1
source share
1 answer

The point at which you should change your code is when your new instance of SSLSocketFactory:

 return new SSLSocketFactory(truststore); 

The SSLSocketFactory class has other constructors, one of which allows you to specify a keystore, key store password, and trust:

public SSLSocketFactory (KeyStore keystore, String keystorePassword, KeyStore truststore) ( JavaDoc )

I'm not sure if you can download the .P12 file for Android as a KeyStore (on J2SE you can). If you fail to convert the .P12 file to a Bouncy keystore, similar to the trust store you are already using. Use this keystore to create an instance of SSLSocketFactory and you can use the client certificate.

Import a P12 file into BKS via Portecle

Creating a BKS file and importing an existing .key + .pem very simple using the Portecle GUI (Java program). After starting Portecle, choose File → New Keystore → BKS. After that, you can run Tools → Import Key Pair and select the .P12 file. Finally, save the password-protected key store of your choice.

+3
source

Source: https://habr.com/ru/post/928034/


All Articles