简体   繁体   中英

Android rest client with SSL to specific certificate

I'am trying to connect to SSL rest service from Android. The server uses a SSL cert that is not from a common CA (Thawte, Verisign...)

I'have used this example to proceed: http://blog.antoine.li/2010/10/22/android-trusting-ssl-certificates/

However, although I've done all the steps mentioned (create a BKS provider, create aa custom SchemeRegistry) I have still the error: "No peer certificate".

The code to call the service (from an AsyncTask):

DefaultHttpClient client = new MyHttpClient(mainActivity[0].getApplicationContext());
HttpGet get = new HttpGet("<url of the service>");
get.addHeader("Autorization","Basic YW5kcm9pZDo=");
// Execute the GET call and obtain the response
HttpResponse getResponse;
try {
  getResponse = client.execute(get);
  ....

The code of the MyHttpClient is the same of the blog example. Doing the client.execute(get) crashes with the execption:

01-06 21:47:03.615: W/System.err(19289): javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
01-06 21:47:03.625: W/System.err(19289):    at org.apache.harmony.xnet.provider.jsse.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:137)
01-06 21:47:03.630: W/System.err(19289):    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:93)
01-06 21:47:03.635: W/System.err(19289):    at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:381)
01-06 21:47:03.640: W/System.err(19289):    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:165)
01-06 21:47:03.645: W/System.err(19289):    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
01-06 21:47:03.645: W/System.err(19289):    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
01-06 21:47:03.645: W/System.err(19289):    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
01-06 21:47:03.650: W/System.err(19289):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
01-06 21:47:03.650: W/System.err(19289):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
01-06 21:47:03.650: W/System.err(19289):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
01-06 21:47:03.650: W/System.err(19289):    at validatedid.helloworldandroid.DownloadDevicePendingDocsTask.doInBackground(DownloadDevicePendingDocsTask.java:41)
01-06 21:47:03.650: W/System.err(19289):    at validatedid.helloworldandroid.DownloadDevicePendingDocsTask.doInBackground(DownloadDevicePendingDocsTask.java:1)
01-06 21:47:03.655: W/System.err(19289):    at android.os.AsyncTask$2.call(AsyncTask.java:264)
01-06 21:47:03.655: W/System.err(19289):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
01-06 21:47:03.655: W/System.err(19289):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
01-06 21:47:03.655: W/System.err(19289):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
01-06 21:47:03.660: W/System.err(19289):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
01-06 21:47:03.660: W/System.err(19289):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
01-06 21:47:03.660: W/System.err(19289):    at java.lang.Thread.run(Thread.java:856)

In some places say it could be an error from the server but I don't know how to check that. Any help would be really apreciated.

Thanks in advance.

Looking more into stackoverflow I find the solution to the problem.

Looks like using the code from http://blog.antoine.li/2010/10/22/android-trusting-ssl-certificates/ is not enough (at least for me).

SSLSocketFactory needs to be subclassed. Full explanation in: Trusting all certificates using HttpClient over HTTPS

I leave here the answer in case anybody arrives here.

I hope in next versions of Android it will be a easier way to acces rest services with https because is a common task and currently is not very easy.

I used -> this <- to make my Https Self-Signed Certificate connections, without disabling certificate or host validation, so it's REALLY secure from SSL pov.

In resume, need to create a Custom Keystore on your app so you can validate your server HTTP against the app KeyStore.

It's dissapointing to see that too much people consider disabling SSL validations a correct answer to this type of questions, when in fact, the whole point of SSL is Security and Validations. If you intend to avoid any validation, just stick to plain HTTP

Please refer to this answer i've recently made on another question

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM