Trusting all certificates using HttpClient over HTTPS

0 votes

Recently posted a question regarding the HttpClient over Https. I've made some headway, but I've run into new issues. As with my last problem, I can't seem to find an example anywhere that works for me. Basically, I want my client to accept any certificate (because I'm only ever pointing to one server) but I keep getting a javax.net.ssl.SSLException: Not trusted server certificate exception.

So this is what I have:

public void connect() throws A_WHOLE_BUNCH_OF_EXCEPTIONS {

    HttpPost post = new HttpPost(new URI(PROD_URL));
    post.setEntity(new StringEntity(BODY));

    KeyStore trusted = KeyStore.getInstance("BKS");
    trusted.load(null, "".toCharArray());
    SSLSocketFactory sslf = new SSLSocketFactory(trusted);
    sslf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

    SchemeRegistry schemeRegistry = new SchemeRegistry();
    schemeRegistry.register(new Scheme ("https", sslf, 443));
    SingleClientConnManager cm = new SingleClientConnManager(post.getParams(),
            schemeRegistry);

    HttpClient client = new DefaultHttpClient(cm, post.getParams());
    HttpResponse result = client.execute(post);
}

And here's the error I'm getting:

W/System.err(  901): javax.net.ssl.SSLException: Not trusted server certificate 
W/System.err(  901):    at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:360) 
W/System.err(  901):    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:92) 
W/System.err(  901):    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:321) 
W/System.err(  901):    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:129) 
W/System.err(  901):    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) 
W/System.err(  901):    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) 
W/System.err(  901):    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:348) 
W/System.err(  901):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 
W/System.err(  901):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 
Jun 25, 2018 in Java by developer_1
• 3,350 points
11,557 views

1 answer to this question.

0 votes

Note: Do not implement this in production code you are ever going to use on a network you do not entirely trust. Especially anything going over the public internet.

Your question is just what I want to know. After I did some searches, the conclusion is as follows.

In HttpClient way, you should create a custom class from org.apache.http.conn.ssl.SSLSocketFactory, not the one org.apache.http.conn.ssl.SSLSocketFactory itself. Some clues can be found in this post Custom SSL handling stopped working on Android 2.2 FroYo.

An example is like ...

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;
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();
    }
}

and use this class while creating instance of HttpClient.

public HttpClient getNewHttpClient() {
    try {
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        trustStore.load(null, null);

        MySSLSocketFactory sf = new MySSLSocketFactory(trustStore);
        sf.setHostnameVerifier(SSLSocketFactory.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();
    }
}

BTW, the link below is for someone who is looking for HttpURLConnection solution. Https Connection Android

I have tested the above two kinds of solutions on froyo, and they all work like a charm in my cases. Finally, using HttpURLConnection may face the redirect problems, but this is beyond the topic.

Note: Before you decide to trust all certificates, you probably should know the site full well and won't be harmful of it to end-user.

Indeed, the risk you take should be considered carefully, including the effect of hacker's mock site mentioned in the following comments that I deeply appreciated. In some situation, although it might be hard to take care of all certificates, you'd better know the implicit drawbacks to trust all of them.

answered Jun 25, 2018 by Rishabh
• 3,620 points

Related Questions In Java

0 votes
1 answer

Java Client Certificate over HTTPS/SSL

The missing links was (mostly) the first ...READ MORE

answered Nov 28, 2018 in Java by Sushmita
• 6,920 points
6,795 views
0 votes
1 answer

Http Basic Authentication in Java using HttpClient?

String encoding = Base64Encoder.encode ("test1:test1"); HttpPost httppost = ...READ MORE

answered Dec 20, 2018 in Java by Daisy
• 8,140 points
4,224 views
0 votes
2 answers

How do I get the current date and time using Java?

If you require a time stamp in ...READ MORE

answered Aug 23, 2019 in Java by Sirajul
• 59,230 points
2,934 views
0 votes
2 answers

How can I create File and write data in it using Java?

import java.io.BufferedWriter; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; public class WriteFiles{ ...READ MORE

answered Jul 26, 2018 in Java by samarth295
• 2,220 points
2,923 views
0 votes
2 answers

Send HTTP request in Java

import com.google.api.client.http.GenericUrl; import com.google.api.client.http.HttpRequest; import com.google.api.client.http.HttpResponse; import com.google.api.client.http.HttpTransport; import com.google.api.client.http.javanet.NetHttpTransport; import java.io.IOException; import ...READ MORE

answered Aug 3, 2018 in Java by samarth295
• 2,220 points
1,747 views
+1 vote
13 answers

How to send HTTP POST requests on Java?

With Apache HttpClient In the old days, this Apache ...READ MORE

answered Dec 10, 2020 in Java by Rajiv
• 8,870 points
159,397 views
0 votes
2 answers

Performing HTTP POST operation in JAVA

I'm using JSON-Java to build my JSON object: JSONObject json ...READ MORE

answered Nov 26, 2018 in Java by Sushmita
• 6,920 points
4,618 views
0 votes
12 answers

Java - sending HTTP parameters via POST method easily

Below are the steps we need to ...READ MORE

answered Dec 11, 2020 in Java by Rajiv
• 8,870 points
111,046 views
0 votes
3 answers

Adding text to a file using Java

try { final Path ...READ MORE

answered Sep 6, 2018 in Java by Sushmita
• 6,920 points
1,413 views
0 votes
1 answer

How to download and save a file from Internet using Java?

public void saveUrl(final String filename, final String ...READ MORE

answered May 25, 2018 in Java by Rishabh
• 3,620 points
914 views
webinar REGISTER FOR FREE WEBINAR X
REGISTER NOW
webinar_success Thank you for registering Join Edureka Meetup community for 100+ Free Webinars each month JOIN MEETUP GROUP