Like so many here, I'm trying to communicate with a site that has a self-signed cert. There are many many classes and code snippets showing how to do this, e.g. HTTPS GET (SSL) with Android and self-signed server certificate, but I can't find any that show how to actually use the classes. I've experimented a great deal, and I'm sure I'm just missing something simple.
To be specific, I am trying to use the classes supplied by "Moss"; the answer with the most votes. I still always get the "Not trusted cert" message. One other person in that topic has also asked for implementation hints, but has not been answered. Thanks for any help.
If I could append this question to that topic, I'd be much happier, but I guess newbies like me can only post new questions (although I've been a fan of SO for over a year).
We use a similar SocketFactory
and X509TrustManager
implementation in some of our projects. In order to bind these classes up to your implementation, all you basically should have to do is hook them up to the HttpClient
(assuming that's what you're using) used for client-server communication.
We normally have a method to create an HttpClient
with the mentioned factory and trustmanager. It looks somewhat like this and is loosely based on the link shown in the inline comments.
protected HttpClient constructClient() {
HttpParams params = new BasicHttpParams();
params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
// use the debug proxy to view internet traffic on the host computer
if (ABCApplication.isDebuggingProxy()) params.setParameter(ConnRoutePNames.DEFAULT_PROXY, new HttpHost(ABCConstants.DEBUG_PROXY_HOST, ABCConstants.DEBUG_PROXY_PORT, "http"));
// ignore ssl certification (due to signed authority not appearing on android list of permitted authorities)
// see: http://blog.antoine.li/2010/10/22/android-trusting-ssl-certificates/
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", new PlainSocketFactory(), 80));
registry.register(new Scheme("https", new FakeSocketFactory(), 443));
ClientConnectionManager cm = new SingleClientConnManager(params, registry);
return new DefaultHttpClient(cm, params);
}
Hope that helps with your implementation.
We can also use
HttpURLConnection http = null;
URL url;
try {
url = new URL("https:your domian");
if (url.getProtocol().toLowerCase().equals("https")) {
trustAllHosts();
HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
https.setHostnameVerifier(DO_NOT_VERIFY);
http = https;
System.out.println("TEST:::"+convertStreamToString(http.getInputStream()));
} else {
http = (HttpURLConnection) url.openConnection();
System.out.println("TEST:::"+convertStreamToString(http.getInputStream()));
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*******
* Trust every server - don't check for any certificate
*/
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 {
}
} };
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection
.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}
}
final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};