3
votes

I installed localy on my computer an Apache 2 server. First I configured it with 1-way SSL and try to connect with it from Android. In order to configure my own 1-way SSL Apache 2 server I had to create the server certificate. I did it with the following commmands:

openssl genrsa -out server.key 2048

openssl req -config ./openssl.cnf -new -key server.key -out server.req

openssl x509 -req -in server.req -CA ca.cer -CAkey ca.key -set_serial 100 -extfile openssl.cnf -extensions server -days 365 -outform PEM -out server.cer

Then, I took the server.cer file and converting it to BKS using java keytool. The authentication from Android worked. Then, I continued with the 2-way SSL configuration of my Apache 2 server and trying to comunicate with it from Android. I did not manage to make it work... I used the following commands to create the client certificate:

openssl req -config ./openssl.cnf -newkey rsa:2048 -nodes -keyform PEM -keyout ca.key -x509 -days 3650 -extensions certauth -outform PEM -out ca.cer

openssl genrsa -out client.key 2048

openssl req -config ./openssl.cnf -new -key client.key -out client.req

openssl x509 -req -in client.req -CA ca.cer -CAkey ca.key -set_serial 101 -extfile openssl.cnf -extensions client -days 365 -outform PEM -out client.cer

openssl pkcs12 -export -inkey client.key -in client.cer -out client.p12

It works from PC browser after importing the client.p12 file. For Android I converted the client.p12 file to BKS format (using Portecle tool) but it seems not to work. Maybe the conversion is not done correctly ?! I always get javax.net.ssl.SSLPeerUnverifiedException: No peer certificate Exception. Does anyone have any idea what could be the problem ? Here it is the Android code:

  public class SslTestActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    try {
        // load truststore certificate
        InputStream clientTruststoreIs = getResources().openRawResource(
                R.raw.server);
        KeyStore trustStore = KeyStore.getInstance("BKS");
        trustStore.load(clientTruststoreIs, "mypassword".toCharArray());

        System.out.println("---- Loaded server certificates: "
                + trustStore.size());



        // load client certificate
        InputStream keyStoreStream = getResources().openRawResource(
                R.raw.clientt);
        KeyStore keyStore = KeyStore.getInstance("BKS");
        keyStore.load(keyStoreStream, "password".toCharArray());
        System.out
                .println("-------Loaded client certificates: " + keyStore.size());


        // initialize SSLSocketFactory to use the certificate
        SSLSocketFactory socketFactory = new SSLSocketFactory(SSLSocketFactory.TLS,
                keyStore, "password", trustStore, null, null);

        // Set basic data
        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, "UTF-8");


        // 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);
        try {
            String res = executeHttpGet(sClient, "https://10.41.0.102/");
            System.out.println("------- SSL RESULT IS = " + res);
        } catch (Exception e) {
            System.out.println("---- ex " + e.getMessage());
            e.printStackTrace();
        }



    } catch (Exception e) {
        System.out.println("------Exception " + e.getMessage());
        e.printStackTrace();
    }
}

public String executeHttpGet(DefaultHttpClient client, String url) throws Exception {
    BufferedReader in = null;
    try {

        HttpGet request = new HttpGet();
        request.setURI(new URI(url));
        HttpResponse response = client.execute(request);

        in = new BufferedReader(new InputStreamReader(response
                .getEntity().getContent()));
        StringBuffer sb = new StringBuffer("");
        String line = "";
        String NL = System.getProperty("line.separator");
        while ((line = in.readLine()) != null) {
            sb.append(line + NL);
        }
        in.close();
        String result = sb.toString();
        return result;
    } finally {
        if (in != null) {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}}

Thank you

1

1 Answers

2
votes

Your code seems correct. Here's a few things you can try:

  1. List the contents of the key store from Android to make sure the right certificate is there and is parsable.

  2. Turn on SSL debugging on the server side and check the logs

  3. Check logcat to see if there are any errors/warnings.