Ignore SSL Certificate Errors with Java
Asked Answered
B

4

10

Apache Http Client. You can see the relevant code here:

String url = "https://path/to/url/service";
HttpClient client = new HttpClient();
PostMethod method = new PostMethod(url);

// Test whether to ignore cert errors
if (ignoreCertErrors){
  TrustManager[] trustAllCerts = new TrustManager[]{
    new X509TrustManager(){
      public X509Certificate[] getAcceptedIssuers(){ return null; }
      public void checkClientTrusted(X509Certificate[] certs, String authType) {}
      public void checkServerTrusted(X509Certificate[] certs, String authType) {}
    }
  };

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

try {

  // Execute the method (Post) and set the results to the responseBodyAsString()
  int statusCode = client.executeMethod(method);
  resultsBody = method.getResponseBodyAsString();

} catch (HttpException e){
  e.printStackTrace();
} catch (IOException e){
  e.printStackTrace();
} finally {
  method.releaseConnection();
}

This is the method everyone says to use to ignore SSL Certificate Errors (only setting this up for staging, it won't be used in production). However, I am still getting the following exception/stacktrace:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building unable to find valid certification path to requested target

Any tips would be great. If I am doing the TrustManager wrong, or if I should be executing the HTTP Post method differently, either way.

Thanks!

Buffoon answered 21/8, 2012 at 17:46 Comment(4)
Please read the answer to the question you posted (as I did, many times). I am doing what he says, but am still experiencing the problem. Thanks.Buffoon
Please paste your code as part of your question, so that it's self-contained. No need to use Gist/Github for something small like this.Maria
'Everyone' is wrong about that. Ignoring certificate problems makes SSL radically insecure, specifically vulnerable to man-in-the-middle attacks. See the discussion in RFC 2246. It should also be noted that the implementation of X509TrustManager in your link, along with most others I have seen, doesn't comply with the specification.Forceps
@EJP. The poster was not asking for a lecture on security. He wanted to know how to do something.Risotto
M
12

First, don't ignore certificate errors. Deal with them instead. Ignoring certificate errors opens the connection to potential MITM attacks. It's like turning off the buzzer in your smoke alarm because sometimes it makes a noise...

Sure, it's tempting to say it's only for test code, it won't end up in production, but we all know what happens when the deadline approaches: the code doesn't show any error when it's being tested -> we can ship it as it is. You should set up a test CA instead if you need. It's not very hard to make, and the overall process is certainly no harder than introducing custom code for development and removing it in production.

You're visibly using Apache Http Client:

HttpClient client = new HttpClient();
int statusCode = client.executeMethod(method);

Yet, you're initialising the javax.net.ssl.HttpsURLConnection with the SSLContext you've created:

HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());

This is completely independent of the Apache Http Client settings.

Instead, you should set up the SSLContext for the Apache Http Client library, as described in this answer. If you're using Apache Http Client 3.x, you need to set up your own SecureProtocolSocketFactory to use that SSLContext (see examples here). It's worth upgrading to Apache Http Client 4.x though, which has direct support for SSLContext.

You can also use Pascal's answer to import the certificate correctly. Again, if you follow the accepted answer (by Kevin) to that question, you will indeed ignore the error but this will make the connection vulnerable to MITM attacks.

Maria answered 21/8, 2012 at 18:28 Comment(4)
Thanks for this! So basically, I already have code written to handle different 'environments' by loading a .properties file. I am only setting ignorecerterrors to true in localhost.properties, so it won't sneak it's way into production. This is good though, and I will definitely look into it. I'll let you know!Buffoon
Loading different environments via a properties file can work, but you'll still have some insecure code in your code base (which someone else may end-up copying/paster). Overall, having an internal test CA makes much more realistic tests that don't require code change (only configuration).Maria
I'm not 100% sure what a test CA is, would you mind enlightening?Buffoon
Well, just create your own CA and issue certificates with it. In your dev environment, set up your services to use these certificates and import the CA cert itself into the truststore of the clients. This is viable in a test/dev environment, and there are tools to help you with this (e.g. OpenSSL's CA.pl or TinyCA).Maria
R
2

HttpClient 4.3, it's easy,

     HttpClientBuilder cb = HttpClientBuilder.create();
     SSLContextBuilder sslcb = new SSLContextBuilder();
     sslcb.loadTrustMaterial(KeyStore.getInstance(KeyStore.getDefaultType()), new TrustSelfSignedStrategy());
     cb.setSslcontext(sslcb.build());
     CloseableHttpClient httpclient = cb.build();

that should fix ur problem

Reinhard answered 2/9, 2014 at 9:41 Comment(0)
P
2

If you really want to ignore everything this worked for me:

SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(new TrustStrategy() {
    @Override
    public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        return true;
    }
}).build();
HostnameVerifier hnv = new NoopHostnameVerifier();      
SSLConnectionSocketFactory sslcf = new SSLConnectionSocketFactory(sslContext, hnv);     
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslcf).build()
Probate answered 28/9, 2017 at 12:40 Comment(0)
E
0

Ignoring certificates has it's own harm, because the same code can move in production enviornment, and can cause havoc.

Below example is with Jersey Rest Client

private static final com.sun.jersey.api.client.Client client = com.sun.jersey.api.client.Client.create(configureClient());
final com.sun.jersey.api.client.WebResource webResource = client.resource("url");
try {
    com.sun.jersey.api.client.ClientResponse response = webResource.type(MediaType.APPLICATION_JSON_TYPE)
                            .accept(MediaType.APPLICATION_JSON_TYPE)
                            .get(com.sun.jersey.api.client.ClientResponse.class);
}catch(com.sun.jersey.api.client.ClientHandlerException che){
    che.printStackTrace();  
}

And ignoring certificates can be as below:

public static ClientConfig configureClient() {
    TrustManager[ ] certs = new TrustManager[ ] {
            new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
            }
    };
    SSLContext ctx = null;
    try {
        ctx = SSLContext.getInstance("SSL");
        ctx.init(null, certs, new SecureRandom());
    } catch (java.security.GeneralSecurityException ex) {
    }
    HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());

    ClientConfig config = new DefaultClientConfig();
    try {
        config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(
                new HostnameVerifier() {
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                },
                ctx
        ));
    } catch(Exception e) {
    }

    return config;
}
Excoriate answered 16/3, 2017 at 1:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.