2016-06-29 1 views
11

Je développe une application simple qui utilise le protocole https pour publier et obtenir des données du serveur. J'ai cherché sur internet mais il y a peu de ressources disponibles, j'ai essayé la plupart d'entre eux mais je n'ai pas pu le faire avec succès.HttpsURLconnection pour publier et entrer dans Android

J'ai essayé avec HttpClient ce fut le succès, mais je veux le faire avec HttpsURLConnection

Dois-je prendre la clé publique RSA de l'appareil, si oui, comment puis-je faire cela.

Quelqu'un peut-il me dire comment puis-je y parvenir en utilisant 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; 
} 

La plupart du temps, je reçois obtenir l'erreur:

Caused by: `java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.` 
+1

Peut-être que vous vérifiez ce message d'erreur? http://stackoverflow.com/questions/6825226/trust-anchor-not-found-for-android-ssl-connection –

+0

Est-ce que celui-ci aidera? http://www.compiletimeerror.com/2013/01/login-application-for-android-android.html#.Vue4EOb35zl Surtout le point numéro 4? – Stallion

+0

Essayez d'utiliser la bibliothèque Volley. J'espère que cela aide! –

Répondre

0

Créez d'abord un magasin clé et SSL Socket Factory.

public HttpClient getNewHttpClient() { 
     try { 
      KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
      trustStore.load(null, null); 

      MySSLSocketFactory sf = new MySSLSocketFactory(trustStore); 
      sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 

      HttpParams params = new BasicHttpParams(); 
      HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
      HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); 

      SchemeRegistry registry = new SchemeRegistry(); 
      registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); 
      registry.register(new Scheme("https", sf, 443)); 

      ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry); 
      return new DefaultHttpClient(ccm, params); 
     } catch (Exception e) { 
      return new DefaultHttpClient(); 
     } 
    } 

Ensuite, dans votre AsyncTask faire ce

@Override 
     protected String doInBackground(String... arg0) { 
      try { 
       //Post Username and password 
       HttpClient httpclient = getNewHttpClient(); 
       String secondParameter = applicationEnvironment.getForgetPasswordSecondParameter(context); 
       String user_base_url = BASEURL +"Account/ForgotPassword?Email="+arg0[0]; 
       HttpPost httppost = new HttpPost(user_base_url); 
       List<BasicNameValuePair> nameValuePairs = new ArrayList<>(1); 
       nameValuePairs.add(new BasicNameValuePair("Email", arg0[0])); 
       httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 

       // Execute HTTP Post Request 
       HttpResponse response = httpclient.execute(httppost); 
       HttpEntity entity = response.getEntity(); 
       String responseString = EntityUtils.toString(entity, "UTF-8"); 
       Log.d("Results ", responseString); 
       return responseString; 
      } catch (UnsupportedEncodingException e) { 
       e.printStackTrace(); 
      } catch (ClientProtocolException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      return null; 
     } 
2

J'utilise le code suivant dans mon application pour publier des données sur mon serveur et lire la réponse.

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.

Vous pouvez voir que l'utilisation du protocole https est almostly même que l'utilisation de http.

code

pour 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()); 
}