tags:

views:

8057

answers:

7

I am doing a https post and I'm getting an exception of ssl exception Not trusted server certificate. If i do normal http it is working perfectly fine. Do I have to accept the server certificate somehow?

+1  A: 

I don't know about the Android specifics for ssl certificates, but it would make sense that Android won't accept a self signed ssl certificate off the bat. I found this post from android forums which seems to be addressing the same issue: http://androidforums.com/android-applications/950-imap-self-signed-ssl-certificates.html

Matti
what is the solution for the same to get an https connection ...
Sam97305421562
Http Post method will work for the same ?
Sam97305421562
Like I said I don't know the Android specifics but I's day that you have to tell the platform what the ssl certificate of the server you are connecting to is. That is if you are using a self signed cert that's not recognized by the platform. The SslCertificate class will probably be helpful:http://developer.android.com/reference/android/net/http/SslCertificate.htmlI'll dig into this later today when I have more time.
Matti
+3  A: 

I'm making a guess, but if you want an actual handshake to occur, you have to let android know of your certificate. If you want to just accept no matter what, then use this pseudo-code to get what you need with the Apache HTTP Client:

SchemeRegistry schemeRegistry = new SchemeRegistry ();

schemeRegistry.register (new Scheme ("http",
    PlainSocketFactory.getSocketFactory (), 80));
schemeRegistry.register (new Scheme ("https",
    new CustomSSLSocketFactory (), 443));

ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager (
    params, schemeRegistry);


return new DefaultHttpClient (cm, params);

CustomSSLSocketFactory:

private SSLSocketFactory FACTORY = HttpsURLConnection.getDefaultSSLSocketFactory ();

public CustomSSLSocketFactory
(
)
    {
    try
        {
        SSLContext context = SSLContext.getInstance ("TLS");
        TrustManager[] tm = new TrustManager[] { new FullX509TrustManager () };
        context.init (null, tm, new SecureRandom ());

        FACTORY = context.getSocketFactory ();
        }
    catch (Exception e)
        {
        e.printStackTrace();
        }
    }

public Socket createSocket() throws IOException
{
    return FACTORY.createSocket();
}

FullX509TrustManager is a class that implements javax.net.ssl.X509TrustManager, yet none of the methods actually perform any work.

Good Luck!

Nate
Why is there the FACTORY variable??
Codevalley
Clarified in post. You need FACTORY for the other override methods a SocketFactory needs to create a socket.
Nate
return FACTORY.createSocket(); is having problem. The created socket is giving null Pointer exception on execute(). Also, I noticed, there are 2 SocketFactory classes. 1. org.apache.http.conn.ssl.SSLSocketFactory and 2. javax.net.ssl.SSLSocketFactory
Codevalley
Sorry, I think after little more digging, I found the problem, I have to implement the connectSocket() function, which by default returns null. Any idea on this?
Codevalley
+4  A: 

This is what I am doing. It simply doesn't check the certificate anymore.

// always verify the host - dont check for certificate
final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
 public boolean verify(String hostname, SSLSession session) {
  return true;
 }
};

/**
 * Trust every server - dont check for any certificate
 */
private static void trustAllHosts() {
 // Create a trust manager that does not validate certificate chains
 TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
  public java.security.cert.X509Certificate[] getAcceptedIssuers() {
   return new java.security.cert.X509Certificate[] {};
  }

  public void checkClientTrusted(X509Certificate[] chain,
    String authType) throws CertificateException {
  }

  public void checkServerTrusted(X509Certificate[] chain,
    String authType) throws CertificateException {
  }
 } };

 // Install the all-trusting trust manager
 try {
  SSLContext sc = SSLContext.getInstance("TLS");
  sc.init(null, trustAllCerts, new java.security.SecureRandom());
  HttpsURLConnection
    .setDefaultSSLSocketFactory(sc.getSocketFactory());
 } catch (Exception e) {
  e.printStackTrace();
 }
}

and

 HttpURLConnection http = null;

 if (url.getProtocol().toLowerCase().equals("https")) {
     trustAllHosts();
  HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
  https.setHostnameVerifier(DO_NOT_VERIFY);
  http = https;
 } else {
  http = (HttpURLConnection) url.openConnection();
 }
Ulrich Scheller
hey thnx .... :-)
Sam97305421562
This looks good! I'm using WebView, however, and only need to connect to a https server for test purposes. (The client can't provision one with a matching FQDN, nor can they test on http.) Is there any way to tackle this when using WebView? Do I just drop this code in the Activity where the WebView is and "it just works?" (Suspecting not … ??)
Joe D'Andrea
A: 

may this thread help, but i can not tell if it works will latest API :

http://groups.google.com/group/android-developers/browse%5Fthread/thread/1ac2b851e07269ba/c7275f3b28ad8bbc?#c7275f3b28ad8bbc

rzr
+1  A: 

While trying to answer this question I found a better tutorial. With it you don't have to compromise the certificate check.

http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html

*I did not write this but thanks to Bob Lee for the work

bajohns
A: 

Also found a good tutorial, very similar to cryzybobs.

This solution also doesn't compromise certificate checking and explains how to add the trusted certs in your own keystore.

http://blog.antoine.li/index.php/2010/10/android-trusting-ssl-certificates/

saxos
A: 

None of these worked for me (aggravated by the Thawte bug as well see http://bit.ly/bypAk2). Eventually I got it fixed with http://stackoverflow.com/questions/1217141/self-signed-ssl-acceptance-android and http://stackoverflow.com/questions/2899079/custom-ssl-handling-stopped-working-on-android-2-2-froyo

aspinei