Как доверять добавленный пользователем сертификат в Android? - PullRequest
0 голосов
/ 24 мая 2019

Я хочу протестировать производственное приложение с Android на локальном сетевом сервере с самозаверяющим сертификатом. Чтобы сделать это в iOS, я могу добавить сертификат на устройство, и оно будет доверенным, поэтому я могу использовать приложение с этим сервером.

Когда я добавляю его с помощью Wi-Fi> Advance-> Install Certificate на большинстве устройств, приложение не работает.

Единственное, где оно работает, это устройство MIUI (Android 6.0.1), которое имеет рутированные права. Требуется ли быть доверенным, чтобы иметь возможность доверять сертификату?

1 Ответ

0 голосов
/ 24 мая 2019

Чтобы использовать самозаверяющие сертификаты, вам нужно создать диспетчер доверия.

Менеджер доверия обрабатывает проверку сертификатов, и это часть программы, которая выдает 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:

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

...