4
votes

In the app I'm working on, I have to make an HTTPS connection to a web server. I was getting certificate not trusted errors and after consulting stackoverflow, I found this blog posting: http://blog.antoine.li/index.php/2010/10/android-trusting-ssl-certificates/

It seems like the CA for this server is not included in Android's default store. In a nutshell, I downloaded all the certificates, created a keystore with the BKS provider, imported the keys, imported the keystore into my project, subclassed the DefaultHttpClient class to force it to use my keystore.

After following the steps in the blog, it worked perfectly on the emulator. However, when I test it on a device, it fails intermittently. I think I've isolated a pattern. It seems like after some time has passed and I try to make an HTTPS connection, it will fail. Then, if I attempt the same connection again, it will succeed. If I wait a while and then try again, it fails the first time, succeeds on repeated attempts. I can probably fix it by just making multiple attempts on failure, but I would like to know what is going on. The behavior suggests some kind of cache but I don't know how to go about finding it or modifying its behavior. Does anyone have any suggestions about what is going on or know what I'm doing wrong? Any help would be appreciated.

2

2 Answers

1
votes

Pure speculation, but I've dealth with similar situations a while back in a Windows/IE environment where the cert was failing intermittently. In both occasions I had proxies that I didn't realize were acting as proxies interfering.

The first one was Fiddler - a web debugger, which was proxying the cert to the browser when I had it engaged.

The second time I had an issue with our corporate internet filtering solution (Web Sense) also acting as a proxy, sort of - it would allow the cert information through correctly eventually but not on the first try.

I don't know if this is your case, but that's the only time I've ever seen behavior like what you're describing.

0
votes

Before open connection, you can create a TrustManager that doest not validate the certificate chains, and install it to your HttpsURLConnection. See below:

`

private static void trustAllHosts() {
    // Create a trust manager that does not validate certificate chains
    TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return new java.security.cert.X509Certificate[] {};
        }

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

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


    try {
        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection
                .setDefaultSSLSocketFactory(sc.getSocketFactory());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

`