Friday, July 8, 2011

Allow untrusted certificate for Https Connection Android

Many a times we need to connect to our Test servers over Https Connection. well its not easy to do that as android do not handles those certificates for you.. Hence your application needs to have a hack for overcoming this .... Here is the code to do so.... All you need to do is ... Create a class and call the function before any of your Https Connection.

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

/**
 * Class will be working as helper to allow fake certificates (i.e Untrusted certificates).

 * @author Abhinava Srivastava
 *
 */

/*
 Copyright [2011] [Abhinava Srivastava]

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

public class TrustManagerManipulator implements X509TrustManager {

private static TrustManager[] trustManagers;
private static final X509Certificate[] acceptedIssuers = new X509Certificate[] {};


public boolean isClientTrusted(X509Certificate[] chain) {
return true;
}

public boolean isServerTrusted(X509Certificate[] chain) {
return true;
}


public static void allowAllSSL() {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
SSLContext context = null;
if (trustManagers == null) {
trustManagers = new TrustManager[] { new TrustManagerManipulator() };
}
try {
context = SSLContext.getInstance("TLS");
context.init(null, trustManagers, new SecureRandom());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
HttpsURLConnection.setDefaultSSLSocketFactory(context
.getSocketFactory());
}

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

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

public X509Certificate[] getAcceptedIssuers() {
return acceptedIssuers;
}
}


Now whenever you want to call HttpsUrlConnection just call TrustManagerManipulator.allowAllSSL(); before it see the example below.

public InputStream getInputStream() throws ClientProtocolException,
IOException {

// Need to add this function before https connection. Thats easy.. isint it?
TrustManagerManipulator.allowAllSSL();
HttpsURLConnection connection = (HttpsURLConnection) (new URL("https://192.168.0.1:2314/myHttpsSite"))
.openConnection();
connection.connect();
return connection.getInputStream();
}


Hope it helps :)

11 comments:

Anonymous said...

Thanks so much, this post was very useful. See you.

Naveen said...

Hi Abhinav,
Thanks for your code.
Your code is working fine when i changed the keys with my keys when i integrate the code into my application i am unable to login will you please help me

Thanks
Naveen

Unknown said...

Hi Naveen.. which keys did you change?

Do something ~~ hubertfc said...

It helps a lot~
Thinks so much~

Do something ~~ hubertfc said...

Thanks a lot~
It helps so much~

Anonymous said...

Best and simplest solution I've seen. Thanks!

Thoast said...

Thank you so much, works superb! =)

Yashwanth said...

Hi Abhinav,

Thanks for your code..Its working great...but I am facing Socket Exception when switching to 3G(with proxy). Here is the link that I clearly mentioned my issue. Please help...

http://stackoverflow.com/questions/12617451/android-application-working-on-wifi-and-3gwithout-proxy-but-not-working-on-3g

sameer said...

Thanks for the code.
I was having problem on Android 2.1
The URLConnection::connect() was failing with the following exception :Host<>cannot be verified

Thanks again.

Unknown said...

hi,

where do we make classs, i mean how do i create this

Anonymous said...

Good post,i learn a lot,thank you.
I have asked this question for several times but I didn't find any complete solution until see your blog.By the way,do you have any idea about how I could offer a user-friendly and secure solution to use HTTPS with home-made certificates?
print barcode in Android