2016-06-29 14 views
11

Zajmuję się tworzeniem prostej aplikacji, która używa protokołu https do publikowania i pobierania danych z serwera. Szukałem w Internecie, ale dostępnych jest niewiele zasobów, próbowałem większości z nich, ale nie mogłem tego zrobić z powodzeniem.HttpsURLconnection do publikowania i uzyskiwania dostępu do systemu Android

Próbowałem z HttpClient to był sukces, ale chcę to zrobić z HttpsURLconnection

Czy muszę wziąć klucz publiczny RSA od urządzenia, a jeśli tak, w jaki sposób można to zrobić.

Czy ktoś może mi powiedzieć, jak mogę to osiągnąć, używając 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; 
} 

Większość czasu jestem coraz uzyskiwanie błąd:

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

Może sprawdzić ten komunikat o błędzie? http://stackoverflow.com/questions/6825226/trust-anchor-not-found-for-android-ssl-connection –

+0

Czy to pomoże? http://www.compiletimeerror.com/2013/01/login-application-for-android-android.html#.Vue4EOb35zl Zwłaszcza punkt numer 4? – Stallion

+0

Spróbuj użyć biblioteki Volley. Mam nadzieję, że to pomoże! –

Odpowiedz

0

najpierw utworzyć magazyn kluczy i 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(); 
     } 
    } 

Następnie w AsyncTask zrobić

@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

Używam następujący kod w mojej aplikacji w celu wysłania danych do mojego serwera i odczytać odpowiedź z powrotem.

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

    } 
    } 
} 

Uwaga:

  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.

Widać, że przy użyciu protokołu HTTPS jest almostly taka sama jak przy użyciu http.

Kod 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()); 
} 
Powiązane problemy