Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android self signed certificate: Trust anchor for certification path not found

I know this subject is discussed in many places, but after I went through almost all of them, I have decided to create my first StackOverflow question...

The problem is the following:

I want to connect to a secured webservice (https) that use a certificate to restrict the access, and a username/password to authenticate the user. So i have a client cert (p12 file) and a server cert (pem or der file). I try to use the HttpURLConnection class, because from what I've heard, Apache library will no more be supported on Android.

So this is my implementations (serverCert and clientCert are the full path to my files):

        // Load CAs from our reference to the file
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        InputStream caInput = new BufferedInputStream(new FileInputStream(serverCert));
        X509Certificate serverCertificate;

        try {
            serverCertificate = (X509Certificate)cf.generateCertificate(caInput);
            System.out.println("ca=" + serverCertificate.getSubjectDN());
        } finally {
            caInput.close();
        }
        Log.d(TAG, "Server Cert: " + serverCertificate);

        // Create a KeyStore containing our trusted CAs
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        trustStore.load(null);
        trustStore.setCertificateEntry("my ca", serverCertificate);

        //Load the Client certificate in the keystore
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        FileInputStream fis = new FileInputStream(clientCert);
        keyStore.load(fis,CLIENT_PASSWORD);

        // Create a TrustManager that trusts the CAs in our KeyStore
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(trustStore);

        //Build the SSL Context
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(keyStore, pref.getString(Constants.clientCertificatePassword, "").toCharArray

());


    //Create the SSL context
                SSLContext sslContext = SSLContext.getInstance("TLS");
                sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
...
    //And later, we use that sslContext to initiatize the socketFactory

                urlConnection = (HttpsURLConnection) requestedUrl.openConnection();
         urlConnection.setSSLSocketFactory(CertificateManager.getInstance().getSslContext().getSocketFactory());
...

So i can create my SSLContext, and display my two certificates content. But when i try to execute my HTTPS connection, I get the following exception:

09-23 13:43:30.283: W/System.err(19422): javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

Does one of you ever met the following error? What was your solution?

These are the website i went through (without success):

http://blog.chariotsolutions.com/2013/01/https-with-client-certificates-on.html

http://nelenkov.blogspot.ch/2011/12/using-custom-certificate-trust-store-on.html

like image 721
TheOnlyYam Avatar asked Sep 23 '13 12:09

TheOnlyYam


People also ask

What is a certificate trust anchor?

In a PKI, a trust anchor is a certification authority, which is represented by a certificate that is used to verify the signature on a certificate issued by that trust-anchor. The security of the validation process depends upon the authenticity and integrity of the trust anchor's certificate.

What is CertPathValidatorException?

java.security.cert.CertPathValidatorException. An exception indicating one of a variety of problems encountered when validating a certification path. A CertPathValidatorException provides support for wrapping exceptions. The getCause method returns the throwable, if any, that caused this exception to be thrown.

Can Android certificates be trusted directly?

However, operating systems like Android typically trust only root CAs directly, which leaves a short gap of trust between the server certificate—signed by the intermediate CA—and the certificate verifier, which knows the root CA.

Is the certificate downloaded from the client website a self signed certificate?

EDIT: The downloaded certiface from the client's web site is CA certificate. Not a self signed certificate. W/System.err: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

What to do if the certificate path is not found?

java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. Create new certificate using cerbot. Configure your mail server to use it (the fullchain variant).

Can I Make my App Trust a certificate without a trustmanager?

This works because the attacker can generate a certificate and—without a TrustManager that actually validates that the certificate comes from a trusted source—your app could be talking to anyone. So don't do this, not even temporarily. You can always make your app trust the issuer of the server's certificate, so just do it.


1 Answers

In your code your are creating and initializing a SSLContext but not using it. Maybe you should replace :

urlConnection.setSSLSocketFactory(CertificateManager.getInstance().getSslContext().getSocketFactory());

by

urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());

I also suggest you if possible to pass the option -Djavax.net.debug=all to the JVM. It will print detailed information about the SSL connection and handshake on the standard output.

like image 175
Jcs Avatar answered Oct 05 '22 01:10

Jcs