Android WebView and ssl self-signed certificates
17 Nov 2009
By r3gis - Android - Permalink
I tried today to code a web application that allow access to a web virtual desktop.
Problem is that this virtual desktop solution could be hosted on a web server with a self-signed certificate. By default, android WebView doesn't allow you to handle ssl certificates fault. (In facts, the default behaviour is to display you a blank screen without asking user if he want to accept certificate).
I well know that unsigned certificates should not be a good way to manage security of a website. But the fact is that in some case, you can afford this little weak.
To resolve this problem under IPhone we have to use a private interface of the webview object. That doesn't ensure us that apple will approve application. Besides, we had to find the trick on a web snippet (and wasn't easy to find).
On android, to solve problem, we will also use private interface (not published on sdk but well present in real java class). Process I use may also be applicable to access any other not published interface.
First step : find the private interface.
Use the fact android source code is open !! http://android.git.kernel.org/ So investigate into Browser source code. Here we discover WebViewClient has a perfect method to handle ssl errors. Browser handle it asking user what to do with certificate.
Second step : get corresponding class source
Well here go the tricky part. We will get real java source code (not the one provided by sdk, but the one that is in java class path at runtime on android). In our case, we have emphasized that WebViewClient is the class we want to hack. So just get it from source from git (WebViewClient.java). You also have to get ../net/http/SslError.java. Luckily, WebViewClient has only this dependency on privates methods. If you want to access WebView apis, you may need to get a lot of files. At this point you have to be aware that if private api are private, they could change ! So check by browsing revisions if privates api/code has not changed between different API versions. What we are about to do is potentially overwrite an existing java class.
Third step : override java class
Now, we will import class into android project.
Just replicate packages from sources you get.

Last step : use private api
That's all folk's ;). Now you just have to use new class.
// It could be a private static member, here just for demo
WebViewClient mWebviewclient = new WebViewClient(){
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error){
handler.proceed();
}
};
//Where myWebview is the WebView object
myWebView.setWebViewClient(mWebviewclient);
Here I just proceed if i detect an ssl certificate error. A good idea should be to check we are talking to the good website (IP configured into you application, and maybe also consider connection type and maybe finally get certificate to be able to compare later).
Comments
This is well done and looked like a lifesaver until I actually tried to duplicate this. And compiling is fine. But when it comes to run it, nothing happens on sslerror sites (stock browser shows the problem as a dialog). Is it possible to attach a working sample?
gstringThansk!
Was looking for a fix some time now and this one works, good job!
TinuzHope that it will be fixed in android though :)
Worked like a charm! Thanks so much for the tip!
AlA lot of thanks for this post, I need it.
I will put a link to this post in the Android Developers Group, this post must be known. I have an open question in the group and you have resolve my question.
psaltamontesThanks for information!
AnnHello! How i may contact the administrator of a site? I have a question.
Faletedon't how is this working, there are so many dependencies in SslErrorHandler.
MikeThanks!
BertrandWorked like a charm for me too!
Regards
Hi,
It works,but need to the one method in web view
@Override
public void onReceivedSslError(WebView view,
SslErrorHandler handler, SslError error) {
handler.proceed();
}
Thank you
samIt is awesome! It is really works!
GaironBig thanks for this small trick!