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

左心房为你撑大大i 提交于 2019-12-21 04:33:13

问题


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


回答1:


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.



来源:https://stackoverflow.com/questions/18959663/android-self-signed-certificate-trust-anchor-for-certification-path-not-found

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!