2

I've struggling in this issue for a week... I installed a client certificate in the android device. And my application have to upload files to the server with requires the client certificate to do the handshake.

Is there any hints to implement this connection? Thanks...

Icarus
  • 1,335
  • 1
  • 11
  • 24
  • You have to have the certificate of the issuer (the one who signed your client certificate) as trusted certificate (or root certificate) in your client. Also your server has to be configured to force clients to send their certificate (Two way SSL). Do you have this configuration on your server and certificates imported on client? – zaerymoghaddam Sep 19 '13 at 09:39
  • how you creating your httpclient can you post the code? – Biraj Zalavadia Sep 19 '13 at 10:16
  • Thanks all, I have had the configuration on my server and imported on client. It works in android browsers. But don't know how to have a connection in an app. My httpclient is :: HttpClient client = new DefaultHttpClient(); HttpPost post = new HttpPost(url); – Icarus Sep 23 '13 at 03:36

1 Answers1

6

Try the following..

You should have alias of the client certificate, which is stored in keystore of your android device. This you can obtain by using

private void chooseCert() {
        KeyChain.choosePrivateKeyAlias(this, this, // Callback
                new String[] {"RSA", "DSA"}, // Any key types.
                null, // Any issuers.
                null, // Any host
                -1, // Any port
                DEFAULT_ALIAS);
    }

After this you will get the callback . Your class should implement KeyChainAliasCallback

And after this try..

 private void connect(){
            String alias = getAliasForClientCertificate();

            final X509Certificate[] certificates =getCertificateChain(alias);
            final PrivateKey pk = getPrivateKey(alias);



            KeyStore trustStore = KeyStore.getInstance(KeyStore
                    .getDefaultType());


            X509ExtendedKeyManager keyManager = new X509ExtendedKeyManager() {

                @Override
                public String chooseClientAlias(String[] strings, Principal[] principals, Socket socket) {
                    return alias;
                }

                @Override
                public String chooseServerAlias(String s, Principal[] principals, Socket socket) {
                    return alias;
                }

                @Override
                public X509Certificate[] getCertificateChain(String s) {
                    return certificates;
                }

                @Override
                public String[] getClientAliases(String s, Principal[] principals) {
                    return new String[]{alias};
                }

                @Override
                public String[] getServerAliases(String s, Principal[] principals) {
                    return new String[]{alias};
                }

                @Override
                public PrivateKey getPrivateKey(String s) {
                    return pk;
                }
            };

            TrustManagerFactory trustFactory = TrustManagerFactory
                    .getInstance(TrustManagerFactory.getDefaultAlgorithm());

            trustFactory.init(trustStore);

            TrustManager[] trustManagers = trustFactory.getTrustManagers();



            X509TrustManager[] tm = new X509TrustManager[] { new X509TrustManager() {
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

                //            public X509Certificate[] getAcceptedIssuers() {
                //                return certificates;
                //            }

                public X509Certificate[] getAcceptedIssuers() {
                    return certificates;
                }

                public boolean isClientTrusted(X509Certificate[] arg0) {
                    return true;
                }
            public boolean isServerTrusted(X509Certificate[] arg0) {
                return true; 
            }


        } };
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(new KeyManager[] {keyManager}, tm, null);
        SSLContext.setDefault(sslContext);

        URL url = new URL("url..");
        HttpsURLConnection urlConnection = (HttpsURLConnection) url
                .openConnection();
        urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());

        HostnameVerifier hv = new HostnameVerifier() {

            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };
        urlConnection.setHostnameVerifier(hv);


        urlConnection.setInstanceFollowRedirects(false);
        urlConnection.connect();
        int responseCode = urlConnection.getResponseCode();

}

private X509Certificate[] getCertificateChain(String alias) {
        try {
            return KeyChain.getCertificateChain(this, alias);
        } catch (KeyChainException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
}
Swapnil Kale
  • 2,620
  • 2
  • 23
  • 21