Monday, July 4, 2016

Cài đặt Https với Android

Hiện nay đa số các dịch vụ có các thông tin nhạy cảm giao dịch trên mạng đều sử dụng giao thức https. Chính vì vậy, các api từ server gửi đến client cũng được cài đặt thêm SSL để tăng cường bảo mật cho dữ liệu. Với Android, để cài đặt https có thể thực hiện theo các bước như sau :
1. Đầu tiên là custom lại "override" class SSLSocketFactory bằng class có tên là ExSSLSocketFactory
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();
    }
}


2. Tạo 1 custom HttpClient sử dụng lớp ExSSLSocketFactory ở bên trên
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;
     }
 }



3. Đến đây, ta có thể sử dụng HttpClient để request bình thường
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;
 }

4. Done ! Như vậy là chúng ta đã cài đặt thành công việc sử dụng HTTPS trên Android. 
Lưu ý : với các bạn sử dụng thư viện http bên ngoài thì thường nó đã hỗ trợ sẵn và các bạn chỉ việc enable nó lên

No comments:

Post a Comment