accepting HTTPS connections with self-signed certificates
android, ca, httpclient, https, ssl
Solution
The first thing you need to do is to set the level of verification. Such levels is not so much:
- ALLOW_ALL_HOSTNAME_VERIFIER
- BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
- STRICT_HOSTNAME_VERIFIER
Although the method setHostnameVerifier() is obsolete for new library apache, but for version in Android SDK is normal. And so we take `ALLOW_ALL_HOSTNAME_VERIFIER` and set it in the method factory `SSLSocketFactory.setHostnameVerifier()`.
Next, You need set our factory for the protocol to https. To do this, simply call the `SchemeRegistry.register()` method.
Then you need to create a `DefaultHttpClient` with `SingleClientConnManager`. Also in the code below you can see that on default will also use our flag (`ALLOW_ALL_HOSTNAME_VERIFIER`) by the method `HttpsURLConnection.setDefaultHostnameVerifier()`
Below code works for me:
HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
DefaultHttpClient client = new DefaultHttpClient();
SchemeRegistry registry = new SchemeRegistry();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
registry.register(new Scheme("https", socketFactory, 443));
SingleClientConnManager mgr = new SingleClientConnManager(client.getParams(), registry);
DefaultHttpClient httpClient = new DefaultHttpClient(mgr, client.getParams());
// Set verifier
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
// Example send http request
final String url = "https://encrypted.google.com/";
HttpPost httpPost = new HttpPost(url);
HttpResponse response = httpClient.execute(httpPost);
Problem
I'm trying to make HTTPS connections, using `HttpClient` lib, but the problem is that, since the certificate isn't signed by a recognized Certificate Authority (CA) like Verisign,GlobalSIgn, etc., listed on the set of Android Trusted Certificates, I keep getting `javax.net.ssl.SSLException: Not trusted server certificate`. I've seen solutions where you simply accept all certificates, but what if I want to ask the user? I want to get a dialog similar to that of the browser, letting the user decide to continue or not. Preferably I'd like to use the same certificatestore as the browser. Any ideas?