【问题标题】:HttpsURLconnection to post and get in AndroidHttpsURLconnection 在 Android 中发布和获取
【发布时间】:2016-06-29 08:15:58
【问题描述】:

我正在开发一个简单的应用程序,它使用 https 协议从服务器发布和获取数据。我在互联网上搜索但可用的资源很少,我尝试了大多数但无法成功。

我尝试使用 HttpClient 成功,但我想使用 HttpsURLconnection

我是否需要从设备中获取公共 RSA 密钥,如果需要,我该怎么做。

谁能告诉我如何使用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;
}

大多数时候我都会收到错误:

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

【问题讨论】:

标签: android sockets ssl-certificate httpsurlconnection


【解决方案1】:

我在我的应用程序中使用以下代码将数据发布到我的服务器并读回响应。

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

    }
  }
}

注意:

  1. params 包含您要发送到服务器的参数
  2. disableHttpsVerify 用于绕过所有安全检查,以防您的服务器的 CA 不受信任。请参阅下面的代码。

可以看到使用https协议和使用http几乎是一样的。

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

【讨论】:

    【解决方案2】:

    首先创建一个密钥库和 SSL 套接字工厂。

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

    然后在您的 AsyncTask 中执行此操作

    @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;
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多