5

I'm using the Apache HttpClient library to setup a https connection. Unfortunately Android gives me a "Not trusted server certificate" error. If I browse to the site with the phone's browser it validates the certificate correctly, which leads me to believe that I need to make the HttpClient 'aware' of the root certificates on the phone. This is my HttpClient setup code:

HttpParams params = new BasicHttpParams();

HttpConnectionParams.setConnectionTimeout( params, 20000 );
HttpConnectionParams.setSoTimeout( params, 20000 );

HttpProtocolParams.setVersion( params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset( params, HTTP.DEFAULT_CONTENT_CHARSET);
HttpProtocolParams.setUseExpectContinue( params, false);

SchemeRegistry schReg = new SchemeRegistry();
schReg.register( new Scheme( "http", PlainSocketFactory.getSocketFactory(), 80 ) );
schReg.register( new Scheme( "https", SSLSocketFactory.getSocketFactory(), 443 ) );

ClientConnectionManager conMgr = new ThreadSafeClientConnManager( params, schReg );

DefaultHttpClient defaultHttpClient = new DefaultHttpClient( conMgr, params );

return ( defaultHttpClient );

As you can see I do nothing special with the SSLSocketFactory. How can I make the HttpClient library validate my site without adding a custom certificate in the keystore?. Should I create a custom SSLSocketFactory and load the cacerts.bks from the Android phone? In that case I might get problems with different passwords for the keystore on different phones?

Please let me know if you need further information. This SSL stuff is pretty difficult for me.

Lucifer
  • 29,392
  • 25
  • 90
  • 143
Ivo
  • 519
  • 2
  • 9
  • 21
  • I have no problems access HTTPS using HttpClient. I'm just using BasicHttpParams and DefaultHttpClient, none of that ClientConnectionManager or SchemeRegistry ... is that necessary for you? – SteelBytes Feb 27 '11 at 11:21
  • http://stackoverflow.com/questions/995514/https-connection-android#1000205 – Peter Knego Feb 27 '11 at 11:28
  • The certificate needs be validated. Installing a 'no check' TrustManager is not preferred, otherwise what would be the point of using ssl at all? I want to be sure that I'm connecting to the right host and that the certificate has not been tempered with. Thanks for the link though. – Ivo Feb 27 '11 at 11:45
  • After a week long looking at blogs, java code and android sources it turns out the problem was in the ordering of the ssl certificates on the site I was connecting to. So, if you encounter problems with certificate validation always double check to see if the certificates are presented to you in the right order and that the root certificate is present on the android device! – Ivo Mar 04 '11 at 10:32

3 Answers3

3

I believe your certificate doesn't contain all intermediate certificates necessary to validate path to a system trusted root certificate. It can be reported as incomplete certificate chain by some SSL config validation tools.

A certificate can contain a special Authority Information Access extension (RFC-3280) with URL to issuer's certificate. Most browsers can use the AIA extension to download missing intermediate certificate to complete the certificate chain. But some clients (mobile browsers, OpenSSL) don't support this extension, so they report such certificate as untrusted.

You can solve the incomplete certificate chain issue manually by concatenating all certificates from the certificate to the trusted root certificate (exclusive, in this order), to prevent such issues. Note, the trusted root certificate should not be there, as it is already included in the system’s root certificate store.

You should be able to fetch intermediate certificates from the issuer and concat them together by yourself. I have written a script to automate the procedure, it loops over the AIA extension to produce output of correctly chained certificates. https://github.com/zakjan/cert-chain-resolver

Community
  • 1
  • 1
zakjan
  • 2,391
  • 1
  • 19
  • 29
0

Following up on zakjan's answer, I had a problem when I tried to use jquery to do an AJAX request on my newly secure server, in an android webview. It worked in the browser, but not in my app.

I used this site: https://certificatechain.io/

I pasted in the text of my signed .crt file I got back from Comodo (positiveSSL), and it gave me back a concatination of everything I needed. I saved it as my domain + "chain.crt" (see below)

Then, in my apache configs, I entered something like this for that particular virtual host:

SSLEngine On
SSLCertificateFile /etc/ssl/localcerts/example_com.crt
SSLCertificateKeyFile /etc/ssl/localcerts/example.com.key
SSLCACertificateFile /etc/ssl/localcerts/example.com.chain.crt

After that, my Android app's webview did not have a problem using ajax to POST to my server. I tried it on 2 real-world devices, one running 2.3.4, one running 4.something. And on the emulator running 2.3. All worked.

I hope this helps.

Richard
  • 1,912
  • 20
  • 28
-2

i have same problem before..

you can use this answer, it works for me nicely..

Trusting all certificates using HttpClient over HTTPS

Community
  • 1
  • 1
pensilhijau
  • 193
  • 3
  • 4
  • 17
  • 11
    Do NOT do this in production! You are turning off all SSL protections. This should only be used for testing internally. Anyone could MITM your requests and steal all sensitive information. – Bishnu Jul 28 '12 at 05:25
  • 1
    I would like to add that now Google rejects every apps which try to bypass this step – StevenTB Oct 03 '16 at 10:13