Virtualzone Heiner Peuser's Blog: Tutorials, How-Tos, Software.

27Feb/117

How to use Apache HttpClient (DefaultHttpClient) with HTTPS/SSL on Android

Connecting to an HTTPS address using the Apache HttpClient shipped with Android is not so straight forward. Whether the server's certificate as correct or not, you will probably see one of these exceptions:

javax.net.ssl.SSLPeerUnverifiedException: No peer certificate.

Here is a "quick and dirty" solution which makes the HttpClient trust any certificate without verifying it (not recommended to be used in productive environments, of course). Read more...

1. Getting the necessary classes

Get the classes EasySSLSocketFactory and EasyX509TrustManager from here.

Open the EasySSLSocketFactory class and modify the following method in this way:

public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
throws IOException, UnknownHostException {
	//return getSSLContext().getSocketFactory().createSocket();
	return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
}

The modification is necessary to avoid the following error:

javax.net.ssl.SSLException: SSL handshake aborted: ssl=0x2cb0e8: I/O error during system call. Broken Pipe

2. Making it work

Use the following code to create an instance of DefaultHttpClient which will accept connections to HTTPS hosts without verifying the SSL certificate:

SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https", new EasySSLSocketFactory(), 443));
 
HttpParams params = new BasicHttpParams();
params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 30);
params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(30));
params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
 
ClientConnectionManager cm = new SingleClientConnManager(params, schemeRegistry);
this.httpClient = new DefaultHttpClient(cm, params);

Source: http://stackoverflow.com/questions/1217141/self-signed-ssl-acceptance-android

Comments (7) Trackbacks (0)
  1. Hi, your post is really clear and I solved my problem.
    I’m really excited because I had struggle with it for a while.
    Actually, I solve thr problem with the classes but one line commented,
    in the else section of the method EasyX509TrustManager.checkServerTrusted(…, String).
    Like this:


    else {
    //standardTrustManager.checkServerTrusted(certificates, authType);
    }
    ….

    and this make my code work for the website.
    Thank you very much!!!!!!!!

    Bset Regards,

    Tom

  2. Many thanks to you. After the hint with


    else {
    //standardTrustManager.checkServerTrusted(certificates, authType);
    }
    ….

    it works perfectly.

    Thank you very much!!!!

    regards
    Michael

  3. Thank you very much. You saved my day…

  4. Thanks man!! It was very helpful!!!

  5. Thank you! Saved me a major headache after reading hours of useless web pages :-)

  6. thanks. it worked!

  7. I can’t resolve my error.
    I follow your method and also Tom’s hint.
    after that, I only execute my httpclient, like this :

    HttpGet method = new HttpGet( internet address );
    method.setHeader(“User-Agent”, FAKE_USER_AGENT);
    HttpResponse res = httpclient.execute(method);

    but, I got follow error messages.
    Could you solve my error?

    02-10 13:02:17.593: W/System.err(2871): javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xf8538: Failure in SSL library, usually a protocol error
    02-10 13:02:17.593: W/System.err(2871): error:14077417:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert illegal parameter (external/openssl/ssl/s23_clnt.c:658 0x40164cc3:0×00000000)
    02-10 13:02:17.593: W/System.err(2871): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:460)
    02-10 13:02:17.593: W/System.err(2871): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream.(OpenSSLSocketImpl.java:643)
    02-10 13:02:17.593: W/System.err(2871): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.getInputStream(OpenSSLSocketImpl.java:614)
    02-10 13:02:17.593: W/System.err(2871): at org.apache.http.impl.io.SocketInputBuffer.(SocketInputBuffer.java:70)
    02-10 13:02:17.593: W/System.err(2871): at org.apache.http.impl.SocketHttpClientConnection.createSessionInputBuffer(SocketHttpClientConnection.java:83)
    02-10 13:02:17.593: W/System.err(2871): at org.apache.http.impl.conn.DefaultClientConnection.createSessionInputBuffer(DefaultClientConnection.java:170)
    02-10 13:02:17.593: W/System.err(2871): at org.apache.http.impl.SocketHttpClientConnection.bind(SocketHttpClientConnection.java:106)
    02-10 13:02:17.593: W/System.err(2871): at org.apache.http.impl.conn.DefaultClientConnection.openCompleted(DefaultClientConnection.java:129)
    02-10 13:02:17.593: W/System.err(2871): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:172)
    02-10 13:02:17.601: W/System.err(2871): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
    02-10 13:02:17.601: W/System.err(2871): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
    02-10 13:02:17.601: W/System.err(2871): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
    02-10 13:02:17.601: W/System.err(2871): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
    02-10 13:02:17.601: W/System.err(2871): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
    02-10 13:02:17.601: W/System.err(2871): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
    02-10 13:02:17.601: W/System.err(2871): at net.yutar.ysapp.YscecNewsParseTask.yscecParse(YscecNewsParseTask.java:146)
    02-10 13:02:17.601: W/System.err(2871): at net.yutar.ysapp.YscecNewsParseTask.doInBackground(YscecNewsParseTask.java:69)
    02-10 13:02:17.601: W/System.err(2871): at net.yutar.ysapp.YscecNewsParseTask.doInBackground(YscecNewsParseTask.java:1)
    02-10 13:02:17.601: W/System.err(2871): at android.os.AsyncTask$2.call(AsyncTask.java:264)
    02-10 13:02:17.601: W/System.err(2871): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
    02-10 13:02:17.601: W/System.err(2871): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
    02-10 13:02:17.601: W/System.err(2871): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
    02-10 13:02:17.601: W/System.err(2871): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
    02-10 13:02:17.601: W/System.err(2871): at java.lang.Thread.run(Thread.java:856)
    02-10 13:02:17.601: W/System.err(2871): Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xf8538: Failure in SSL library, usually a protocol error
    02-10 13:02:17.601: W/System.err(2871): error:14077417:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert illegal parameter (external/openssl/ssl/s23_clnt.c:658 0x40164cc3:0×00000000)
    02-10 13:02:17.609: W/System.err(2871): at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method)
    02-10 13:02:17.609: W/System.err(2871): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:410)
    02-10 13:02:17.609: W/System.err(2871): … 23 more


Leave a comment

(required)

Turn on pictures to see the captcha *

No trackbacks yet.