如何在Android中信任用户添加的证书?

时间:2019-05-24 15:20:22

标签: android ssl-certificate self-signed

我想使用自签名证书在本地网络服务器上的android中测试生产应用。为了在iOS中做到这一点,我可以将证书添加到设备中,该证书将受到信任,因此可以在该服务器上使用该应用程序。

当我在大多数设备中使用Wifi->高级->安装证书将其添加时,该应用将无法正常工作。

它唯一起作用的是根植的MIUI(Android 6.0.1)设备。是否有根植才能信任证书的要求?

1 个答案:

答案 0 :(得分:0)

要使用自签名证书,您需要创建一个信任管理器。

信任管理器负责证书的验证,这是程序的一部分,当您的服务器证书未由可信方签名时,它将抛出SSLHandshakeException

使用自定义信任管理器,您可以选择哪些证书受信任,哪些证书不受信任,即您可以选择信任还是不信任自己喜欢的任何证书。

以下示例显示了如何创建一个信任所有证书的虚拟TrustManager实例:

public class SelfSignedCertActivity extends AppCompatActivity {

    private static final String TAG = "SelfSignedCertActivity";

    // Verifier that verifies all hosts
    private static final HostnameVerifier DUMMY_VERIFIER = new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_self_signed_cert);
    }

    public void onOpenConnectionClick(View view) {

        new OpenConnectionTask().execute();
    }

    private class OpenConnectionTask extends AsyncTask<Void, Void, Boolean> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            // Dummy trust manager that trusts all certificates
            TrustManager localTrustmanager = new X509TrustManager() {

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                @Override
                public void checkServerTrusted(X509Certificate[] chain,
                                               String authType) throws CertificateException {
                }

                @Override
                public void checkClientTrusted(X509Certificate[] chain,
                                               String authType) throws CertificateException {
                }
            };

            // Create SSLContext and set the socket factory as default
            try {
                SSLContext sslc = SSLContext.getInstance("TLS");
                sslc.init(null, new TrustManager[]{localTrustmanager},
                        new SecureRandom());
                HttpsURLConnection.setDefaultSSLSocketFactory(sslc
                        .getSocketFactory());
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (KeyManagementException e) {
                e.printStackTrace();
            }
        }

        @Override
        protected Boolean doInBackground(Void... params) {

            try {
                // Your Server URL goes here
                URL url = new URL("https://selfsigned.tanelikorri.com/");

                HttpsURLConnection connection = (HttpsURLConnection) url
                        .openConnection();
                connection.setHostnameVerifier(DUMMY_VERIFIER);

                // Log the server response code
                int responseCode = connection.getResponseCode();
                Log.i(TAG, "Server responded with: " + responseCode);

                // And if the code was HTTP_OK then return true
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    return true;
                }

            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return false;
        }

        @Override
        protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);

            // Hide progressbar
            setProgressBarIndeterminateVisibility(false);

            if (result != null) {

                // Create a dialog
                Builder builder = new Builder(SelfSignedCertActivity.this);
                if (result) {
                    builder.setMessage("Connection was opened successfully");
                } else {
                    builder.setMessage("Connection failed");
                }
                builder.setPositiveButton("OK", null);

                // and show it
                builder.create().show();
            }
        }
    }
}

更新:

在Android中,无法在设备级别添加自签名服务器证书。但是,您可以通过创建自己的信任管理器在应用程序中信任此类自签名证书。

查看此android doc链接:

https://developer.android.com/training/articles/security-ssl#SelfSigned

我还找到了一个教程,该教程显示了如何将自签名证书添加到android(Chrome和Firefox)的浏览器中,但是仍然不适用于设备范围,只是那些应用程序使您可以信任其中的证书。

https://coderwall.com/p/wv6fpq/add-self-signed-ssl-certificate-to-android-for-browsing