2016-06-29 30 views
11

Sto sviluppando una semplice applicazione che utilizza il protocollo https per pubblicare e ottenere dati dal server. Ho cercato su internet ma ci sono poche risorse disponibili, ho provato la maggior parte di esse ma non ho potuto farlo con successo.HttpsURLconnection per pubblicare e accedere a Android

ho provato con HttpClient era successo, ma voglio farlo con HttpsURLConnection

Ho bisogno di prendere la chiave pubblica RSA dal dispositivo, in caso affermativo come posso farlo.

Qualcuno può dirmi come ottenerlo utilizzando 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; 
} 

maggior parte del tempo sto ottenendo ottenere l'errore:

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

Forse verificare questo messaggio di errore? http://stackoverflow.com/questions/6825226/trust-anchor-not-found-for-android-ssl-connection –

+0

Questo sarà di aiuto? http://www.compiletimeerror.com/2013/01/login-application-for-android-android.html#.Vue4EOb35zl Specialmente il punto numero 4? – Stallion

+0

Provare a utilizzare la libreria Volley. Spero che sia d'aiuto! –

risposta

0

prima creare un archivio chiavi e 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(); 
     } 
    } 

Poi, nel tuo AsyncTask fare questo

@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

Sto utilizzando il seguente codice nella mia app per inviare i dati al mio server e leggere la risposta indietro.

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) { 

    } 
    } 
} 

Nota:

  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.

si può vedere che utilizzando il protocollo HTTPS è almostly lo stesso che con http.

Codice per 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()); 
} 
Problemi correlati