Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpsURLconnection to post and get in Android

I am developing an simple application which uses https protocol to post and get data from the server. I searched on internet but there are few resources available, I tried most of them but couldn't do it successfully.

I tried with HttpClient it was success, but I want to do it with HttpsURLconnection

Do I need to take the Public RSA key from the device, if so how can I do that.

Can someone tell me how can I achieve this using httpsURLconnection.

protected String doInBackground(String... arg0) {     
  try {
    ByteArrayInputStream derInputStream = new ByteArrayInputStream(app.certificateString.getBytes());
    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509","BC");
    X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(derInputStream);
    String alias = "alias";//cert.getSubjectX500Principal().getName();

    KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
    trustStore.load(null);
    trustStore.setCertificateEntry(alias, cert);
    KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
    kmf.init(trustStore, null);
    KeyManager[] keyManagers = kmf.getKeyManagers();

    TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
    tmf.init(trustStore);
    TrustManager[] trustManagers = tmf.getTrustManagers();

    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(keyManagers, trustManagers, null);
    URL url = new URL("MY HTTPS URL");
    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
    conn.setSSLSocketFactory(sslContext.getSocketFactory());

    // set Timeout and method
    conn.setReadTimeout(7000);
    conn.setConnectTimeout(7000);
    conn.setRequestMethod("POST");
    conn.setDoInput(true);

    // Add any data you wish to post here
    conn.connect();
    String reult = String.valueOf(conn.getInputStream());
    Log.d("connection : ", String.valueOf(reult));

  } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
  } catch (IOException e) {
    e.printStackTrace();
  }  catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
  } catch (KeyManagementException e) {
    e.printStackTrace();
  } catch (CertificateException e) {
    e.printStackTrace();
  } catch (KeyStoreException e) {
    e.printStackTrace();
  } catch (NoSuchProviderException e) {
    e.printStackTrace();
  } catch (UnrecoverableKeyException e) {
    e.printStackTrace();
  }
  return null;
}

Most of the time I am getting getting the error:

Caused by: `java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.`
like image 254
Sathya Baman Avatar asked Jun 29 '16 08:06

Sathya Baman


People also ask

What is the difference between HttpURLConnection and HttpsURLConnection?

URLConnection is the base class. HttpURLConnection is a derived class which you can use when you need the extra API and you are dealing with HTTP or HTTPS only. HttpsURLConnection is a 'more derived' class which you can use when you need the 'more extra' API and you are dealing with HTTPS only.

What is HTTP URL connection in Android?

HttpsURLConnection. HttpsURLConnection. HttpsURLConnection extends HttpURLConnection with support for https-specific features. The abstract class URLConnection is the superclass of all classes that represent a communications link between the application and a URL.

Can I use HttpURLConnection for https?

HttpsURLConnection extends HttpURLConnection , and your connection is an instance of both. When you call openConnection() the function actually returns an HttpsURLConnection . However, because the https object extends the http one, your connection is still an instance of an HttpURLConnection .


1 Answers

I'm using the following code in my app to post data to my server and read the response back.

boolean DEBUG = false;

private static String sendHttpsPost(String d, Map<String, String> params) {
  if(DEBUG)disableHttpsVerify(null);
  BufferedReader bis = null;
  InputStream in = null;
  OutputStream out = null;
  try {
    URL url = new URL(d);
    HttpsURLConnection connection = (HttpsURLConnection)url.openConnection();
    connection.setDoOutput(true);
    connection.setDoInput(true);
    connection.setRequestMethod("POST");
    out = connection.getOutputStream();

    StringBuilder sb = new StringBuilder();
    for(Map.Entry<String, String> entry : params.entrySet()) {
      sb.append(entry.getKey());
      sb.append('=');
      sb.append(entry.getValue());
      sb.append('&');
    }
    String str = sb.toString();
    byte[] data = str.substring(0, str.length() - 1).getBytes();
    out.write(data);

    connection.connect();
    in = connection.getInputStream();
    bis = new BufferedReader(new InputStreamReader(in));
    sb.setLength(0);
    while((str = bis.readLine()) != null) {
      sb.append(str);
    }
    return sb.toString();
  } catch (Exception e) {
    return "";
  } finally {
    try {
      if(bis != null) {
        bis.close();
      }
      if(in != null) {
        in.close();
      }
    } catch (Exception x) {

    }
  }
}

Note:

  1. params contains the parameters you want to send to your server
  2. disableHttpsVerify is used to bypass all security checking in case your server's CA is untrusted. See the code below.

You can see that using https protocol is almostly the same as using http.

Code for disableHttpsVerify:

try {
  TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
     @Override
     public X509Certificate[] getAcceptedIssuers() {
       return null;
     }

     @Override
     public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
       // Not implemented
     }

     @Override
     public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
       // Not implemented
     }
   }};
   SSLContext sc = SSLContext.getInstance("TLS");

   sc.init(null, trustAllCerts, new java.security.SecureRandom());

   HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
 } catch (Exception e) {
   LogSaveUtil.savePayLog("disableHttpsVerify" + e.toString());
 }
like image 73
suitianshi Avatar answered Oct 12 '22 23:10

suitianshi