First let me state one thing: DO NOT USE THIS IN A PRODUCTION ENVIRONMENT… EVER!
There are cases though, when you are developing an application, debugging an application or just playing around, that you will need to deal with CertificateExceptions, SSLExceptions and other protection mechanisms that have been put in place for security. This most often occurs when some server admin has generated a self-signed certificate and sent you an IP-address to use for connecting. The certificate will most likely lack correct information such as subject alternative name, common name etc.
If these issues occur, of course you should contact the server admin and have him/her generate a proper certificate. Sometimes though, there is not enough time or good will from the admin side and you have to take extreme measures.
First thing you need to do is make sure you have the Apache HTTP Client library installed.
Then you can create the following class that will create a special SSLSocket that will accept any certificate:
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.conn.ssl.SSLSocketFactory;
/**
* Creates an insecure SSL socket that trusts any certificate.
*
* DO NOT USE IN PRODUCTION ENVIRONMENT!
*
*/
public class MySSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");
public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super(truststore);
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[] { tm }, null);
}
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
}
@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
} |
Then in your class that will be calling the HTTPS URL you can have the following method that will create a new “special” HTTP client:
/**
* Sets up a client that will accept any certificate.
*
* DO NOT USE IN PRODUCTION ENVIRONMENT!
*
* @return the insecure client
*/
private HttpClient getNewHttpClient() {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
MySSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return new DefaultHttpClient();
}
} |
Now that you have an INSECURE HTTP client you can finally make a request. In this example a connection is made to “jsonURL” and fetches some JSON object:
/**
* Reads JSON from the given URL
* @param url
* @return the JSON at the URL
* @throws IOException
* @throws JSONException
*/
private JSONObject readJsonFromUrl() throws IOException, JSONException {
HttpClient httpClient = getNewHttpClient();
String jsonText = getJson(httpClient);
JSONObject json = new JSONObject(jsonText);
return json;
}
/**
* Creates an HTTP(S) request and writes the data to a String
* of JSON.
* @param httpClient the http client to use
* @return a string of JSON
*/
private String getJson(HttpClient httpClient) {
StringBuilder sb = new StringBuilder();
try {
HttpGet getRequest = new HttpGet(jsonURL);
getRequest.addHeader("accept", "application/json");
HttpResponse response = httpClient.execute(getRequest);
String output;
BufferedReader br = new BufferedReader(new InputStreamReader((response.getEntity().getContent())));
while ((output = br.readLine()) != null) {
sb.append(output);
}
} catch (Exception e) {
e.printStackTrace();
}
httpClient.getConnectionManager().shutdown();
return sb.toString();
} |