HttpsURL 连接到 post 并进入 Android

HttpsURLconnection to post and get in Android

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

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

我是否需要从设备中获取 Public 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.`

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

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 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.

可以看到使用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());
 }

首先创建密钥库和 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;
        }