Friday, February 3, 2017

How to access SSL webservice in Android

Most recently I have faced with error when accessing https service in android.The problem was “javax.net.ssl.SSLPeerUnverifiedException: No peer certificate”.So I can’t access it normal way.I searched on internet and had some workaround for fix that problem.

First we need to override SSLSocketFactory and create new one.
 import java.io.IOException;  
 import java.net.Socket;  
 import java.net.UnknownHostException;  
 import java.security.KeyManagementException;  
 import java.security.KeyStore;  
 import java.security.KeyStoreException;  
 import java.security.NoSuchAlgorithmException;  
 import java.security.UnrecoverableKeyException;  
 import java.security.cert.CertificateException;  
 import java.security.cert.X509Certificate;  
 import javax.net.ssl.SSLContext;  
 import javax.net.ssl.TrustManager;  
 import javax.net.ssl.X509TrustManager;  
 import org.apache.http.conn.ssl.SSLSocketFactory;  
 public class ExSSLSocketFactory extends SSLSocketFactory {  
  SSLContext sslContext = SSLContext.getInstance("TLS");  
   public ExSSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {  
     super(truststore);  
     TrustManager x509TrustManager = new X509TrustManager() {  
       public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {  
       }  
       public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {  
       }  
       public X509Certificate[] getAcceptedIssuers() {  
         return null;  
       }  
     };  
     sslContext.init(null, new TrustManager[] { x509TrustManager }, null);  
   }  
   public ExSSLSocketFactory(SSLContext context) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException {  
     super(null);  
     sslContext = context;  
   }  
   @Override  
   public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {  
     return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);  
   }  
   @Override  
   public Socket createSocket() throws IOException {  
     return sslContext.getSocketFactory().createSocket();  
   }  
 }  
after that we have to create modified HttpClient insteed of DefaultHttpClient in apache using created SSLSocketFactory
 public static HttpClient getHttpsClient(HttpClient client) {  
    try{  
       X509TrustManager x509TrustManager = new X509TrustManager() {          
         @Override  
         public void checkClientTrusted(X509Certificate[] chain,  
             String authType) throws CertificateException {  
         }  
         @Override  
         public void checkServerTrusted(X509Certificate[] chain,  
             String authType) throws CertificateException {  
         }  
         @Override  
         public X509Certificate[] getAcceptedIssuers() {  
           return null;  
         }  
       };  
       SSLContext sslContext = SSLContext.getInstance("TLS");  
       sslContext.init(null, new TrustManager[]{x509TrustManager}, null);  
       SSLSocketFactory sslSocketFactory = new ExSSLSocketFactory(sslContext);  
       sslSocketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);  
       ClientConnectionManager clientConnectionManager = client.getConnectionManager();  
       SchemeRegistry schemeRegistry = clientConnectionManager.getSchemeRegistry();  
       schemeRegistry.register(new Scheme("https", sslSocketFactory, 443));  
       return new DefaultHttpClient(clientConnectionManager, client.getParams());  
     } catch (Exception ex) {  
       return null;  
     }  
   }  
Then we can use this HttpClient to deal with https enable service.
 public static String sendData(String id,String name) {  
   String resutString="";  
   StringBuilder builder = new StringBuilder();  
   HttpClient client = Utils.getHttpsClient(new DefaultHttpClient());  
   HttpParams params = new BasicHttpParams();  
     HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);  
     HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);  
     try {  
       //Add your request URL  
       String url = "https://www.webservice/sendnfctag";  
       JSONObject nfcTag=new JSONObject();  
       nfcTag.put("Value", id);  
       nfcTag.put("Other",name);  
       HttpPost httpPost = new HttpPost(url);  
       httpPost.setParams(params);  
       StringEntity entity = new StringEntity(nfcTag.toString(), HTTP.UTF_8);  
       entity.setContentType("application/json");  
       httpPost.setEntity(entity);  
       HttpResponse response = client.execute(httpPost);  
       StatusLine statusLine = response.getStatusLine();  
       int statusCode = statusLine.getStatusCode();  
       if (statusCode == 200) {  
         HttpEntity entityResponse = response.getEntity();  
         InputStream content = entityResponse.getContent();  
         BufferedReader reader = new BufferedReader(new InputStreamReader(content));  
         String line=null;  
         while ((line = reader.readLine()) != null) {  
           builder.append(line+"\n");  
         }  
         reader.close();  
         resutString=builder.toString();  
         Log.d(TAG,"Successfuly :"+resutString);  
       } else {  
         Log.d(TAG,"Error seding data");  
       }  
     } catch (ConnectTimeoutException e) {  
       Log.w("Connection Tome Out", e);  
     } catch (ClientProtocolException e) {  
       Log.w("ClientProtocolException", e);  
     } catch (SocketException e) {  
       Log.w("SocketException", e);  
     } catch (IOException e) {  
       Log.w("IOException", e);  
     } catch (JSONException e) {  
       e.printStackTrace();  
     }  
     return resutString;  
   }  

No comments :

Post a Comment