Android HttpsURLConnection信任证书

时间:2016-03-14 07:43:10

标签: java android

我正在编写与服务器交互的android应用程序。在我的应用程序中,我有几个类扩展了AsyncTask - 一个类用于一个请求。每个类都有URL和HttpURLConnection实例。服务器地址是:https:/myaddress.com(错过一个'/')。我把它留在应用程序字符串资源中。我在我的课程中使用的URL如下所示:https:/myaddress.com/query1,https:/myaddres.com/query2 ... 现在我需要使用Https,在用户开始交互之前,我需要信任CA. 第一个用户的请求是身份验证(类登录)。 如果我将下面的代码放入Login类

KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
String algorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
tmf.init(keyStore);

SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);

URL url = new URL("https://myaddress.com/");
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
urlConnection.setRequestProperty("KeepAlive", true);
InputStream in = urlConnection.getInputStream();
//posting content and handling response
finally {
    in.close();
    urlConnection.disconnect();
}

足以信任CA吗? 我可以确定其他类中的其他HttpsURLConnection实例将使用安全连接吗? 根据文档,我必须对一个请求使用一个HttpsURLConnection实例,但它可以为多个请求/响应对使用相同的底层Socket。我的代码是真的吗?或者我不需要调用disconnect()?

1 个答案:

答案 0 :(得分:0)

我不认为它会以这种方式工作(除非您的证书由本机可信CA提供,但您不需要实例化新的TrustManager)。

以下是我们在应用中使用的内容:

  private static TrustManager[] getTrustManagers(Context context) throws KeyStoreException, NoSuchAlgorithmException, CertificateException
  {
    try
    {
      // Create a KeyStore containing our trusted CAs
      String keyStoreType = KeyStore.getDefaultType();
      KeyStore keyStore = KeyStore.getInstance(keyStoreType);
      keyStore.load(null, null);

      AssetManager assetManager = context.getAssets();

      for (String file : assetManager.list(""))
      {
        if (file.endsWith(".crt"))
        {
          CertificateFactory cf = CertificateFactory.getInstance("X509");
          InputStream caInput = new BufferedInputStream(assetManager.open(file));
          Certificate ca;
          try
          {
            ca = cf.generateCertificate(caInput);
            Log.info(TAG, "CA certificate [" + ((X509Certificate) ca).getSubjectDN() + "] added to truststore.");
          }
          finally
          {
            caInput.close();
          }
          keyStore.setCertificateEntry(file, ca);
        }
      }

      // Create a TrustManager that trusts the CAs in our KeyStore
      String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
      TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
      tmf.init(keyStore);
      return tmf.getTrustManagers();
    }
    catch (IOException e)
    {
      // TODO
      return null;
    }
  }

我们正在捆绑根CA证书的公钥。

  

我可以确定其他类中的其他HttpsURLConnection实例是否会使用安全连接?

HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());

然后,您的所有新HttpsURLConnection都将使用此SocketFactory

  

我的代码是真的吗?或者我不需要调用disconnect()?

每次需要执行请求时,只需执行一个新的HttpsURLConnectionSocketFactory将使用的基础HttpsURLConnection为您处理套接字。 如果您需要在10/20秒内多次调用相同的网址,请不要disconnect,但在一般情况下,您需要disconnect释放所有基础资源。