Вопрос по android, http, ssl, x509certificate, ssl-certificate – принимать самоподписанные сертификаты SSL-> где установить по умолчанию TrustManager

6

Сначала я должен был признать, что знаю, что принятие всех сертификатов может рассматриваться как отсутствие безопасности. У нас есть "реальный» Сертификаты, но только на наших живых системах. Сертификаты в наших тестовых системах являются самозаверяющими. Так что пока мыПри разработке мы должны использовать тест-серверы, что заставляет меня отключать сертификаты.

Здесь, в Stackoverflow и во всем Интернете, я видел множество тем, которые пытаются сделать одно и то же: принимать SSL-сертификаты. Однако ни один из этих ответов, кажется, не относится к моей проблеме, так как яЯ не возиться с.HTTPSUrlConnections

Если я'Когда я делаю запрос, код обычно выглядит так (закомментировано для пояснения):

//creates an HTTP-Post with an URL
HttpPost post = createBaseHttpPost();
//loads the request Data inside the httpPost
post.setEntity(getHttpPostEntity());
//appends some Headers like user-agend or Request UUIDs
appendHeaders(post);

HttpClient client = new DefaultHttpClient();
//mResponse is a custom Object which is returned 
//from the custom ResponseHandler(mResponseHandler) 
mResponse = client.execute(post, mResponseHandler);
return mResponse;

Я прочитал, что я должен вводить свой собственныйTrustManager а такжеX509HostnameVerivier, Я создал их так:

private static final TrustManager[] TRUST_ALL_CERTS = new TrustManager[]{
        new X509TrustManager() {

            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[]{};
            }

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

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

    };

    private static X509HostnameVerifier ACCEPT_ALL_HOSTNAMES = 
            new X509HostnameVerifier() {

                public void verify(String host, String[] cns, String[] subjectAlts)
                        throws SSLException {
                }

                public void verify(String host, X509Certificate cert) throws SSLException {
                }

                public void verify(String host, SSLSocket ssl) throws IOException {
                }

                public boolean verify(String host, SSLSession session) {
                    return true;
                }
            };

Если я введуHostnameVerifier внутри моего запроса, как это (клиент по умолчанию DefaultHttpClient)

SSLSocketFactory ssl = (SSLSocketFactory)client.getConnectionManager().getSchemeRegistry().getScheme("https").getSocketFactory();
ssl.setHostnameVerifier(ACCEPT_ALL_HOSTNAMES);

ответ превращается изимя хоста ** не сделалт матч " к "Плохой запрос ", Я думаю, мне нужно установить TrustManager, но яЯ не знаю, где установить его в моем запросе, как яЯ не использую HttpsUrlConnections, упомянутые везде, где я их искал.

Вместо добавления кода, который пропускает какие-либо сертификаты (то есть кода, который может никогда не быть удален, особенно если вы забудете об этом, когда наступит крайний срок), вы можете рассмотреть возможность запуска собственного тестового CA. Вы'Я должен импортировать этот тестовый сертификат CA в хранилище доверенных сертификатов, но этоБолее реалистичный тест, в том числе с именами хостов (и менее подверженный оставлению плохого кода в выпущенном продукте). Существуют инструменты, которые помогут вам управлять небольшими ЦС. Bruno

Ваш Ответ

1   ответ
9

НетВынуждая вас отключить проверку, это заставляет вас правильно выполнять проверку.Не делайте вслепую принимаю все сертификаты. И нет, ваш случай ничем не отличается, вам просто нужно доверять сертификату, что Android непо умолчанию не доверяю.

Вы используете HttpClient, поэтому API для настройки диспетчера доверия несколько отличаются отHttpsURLConnection, но процедура такая же:

Загрузите файл хранилища ключей с доверенными сертификатами (ваш сервер 'подписанные сертификаты)ИнициализироватьKeyStore с этим.СоздатьSocketFactory с использованиемKeyStore от 2Настройте свою клиентскую библиотеку HTTP, чтобы использовать ее при создании сокетов SSL.

Это описано в Android'едокументация:http://developer.android.com/reference/org/apache/http/conn/ssl/SSLSocketFactory.html

Более подробная статья на эту тему показывает, как создать файл хранилища доверия:http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html

Некоторая справочная информация и пример кода:http://nelenkov.blogspot.com/2011/12/using-custom-certificate-trust-store-on.html

Это код, который вам нужен для инициализации HttpClient:

KeyStore localTrustStore = KeyStore.getInstance("BKS");
InputStream in = getResources().openRawResource(R.raw.mytruststore);
localTrustStore.load(in, TRUSTSTORE_PASSWORD.toCharArray());

SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory
                .getSocketFactory(), 80));
SSLSocketFactory sslSocketFactory = new SSLSocketFactory(localTrustStore);
schemeRegistry.register(new Scheme("https", sslSocketFactory, 443));
HttpParams params = new BasicHttpParams();
ClientConnectionManager cm = 
    new ThreadSafeClientConnManager(params, schemeRegistry);

HttpClient client = new DefaultHttpClient(cm, params); 

На данный момент у вас нет оправданий для доверия всем сертификатам. Если вы это сделаете, это все на вас :)

Похожие вопросы