Нужен ли мне личный сертификат, выполняющий https в Android Java?

Мне нужно получить данные с сервера, говорящего по протоколу https, в мое приложение для Android. Я получаю сертификат сервера динамически, как это:

KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
store.load(null);
URLConnection uc = new URL("https://duckduckgo.com/").openConnection();
uc.connect();
Certificate certs[] = ((HttpsURLConnection) uc).getServerCertificates();
for (int i = 0; i < certs.length; i++) store.setCertificateEntry("cert_"+ i, certs[i]);
((HttpsURLConnection) uc).disconnect();

У меня есть пользовательский HttpClient:

public class MyHttpClient extends DefaultHttpClient {
    final KeyStore store;

    public MyHttpClient(KeyStore store) {
        this.store = store;
    }

    @Override
    protected ClientConnectionManager createClientConnectionManager() {
        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory
                .getSocketFactory(), 80));
        registry.register(new Scheme("https", newSslSocketFactory(), 443));
        return new SingleClientConnManager(getParams(), registry);
    }

    private SSLSocketFactory newSslSocketFactory() {
        try {
            return new SSLSocketFactory(store);
        } catch (Exception e) {
            throw new AssertionError(e);
        }
    }
}

И получает данные с сервера следующим образом:

HttpEntity responseEntity;
URI url = new URI("https://duckduckgo.com/?q=android+java");
HttpGet httpGet = new HttpGet(url );
HttpClient client = new MyHttpClient(store);
httpGet.addHeader("Content-Type", "text/xml");
HttpConnectionParams.setConnectionTimeout(client.getParams(), 15000);
HttpResponse getResponse = client.execute(httpGet);

Все ли я отправляю и получаю в зашифрованном виде?

Я думал, может быть, я должен был предоставить серверу с моим открытым ключом?

2 ответа

Краткий ответ: Нет, вам не нужен сертификат для безопасного взаимодействия с сервером.

Длинный ответ: весь смысл сертификатов заключается в том, что клиент и сервер могут договориться о закрытом ключе шифрования, чтобы никто не знал, что это за ключ. Сертификат сервера будет выдан некоторым крупным центром сертификации (Verisign и т. Д.). Вы можете проверить полномочия, чтобы удостовериться, что они фактически выпустили сертификат для рассматриваемого доменного имени. После того, как вы проверили сертификат на предмет полномочий, вы можете использовать открытый ключ шифрования из сертификата, и только владелец сертификата сможет расшифровать то, что вы зашифровываете. В случае SSL вы используете открытый ключ в сертификате для шифрования ключа шифрования сеанса, который вы будете использовать для безопасной связи с сервером.

При этом не пропускайте проверку сертификата перед его использованием!!!

Я думал, может быть, я должен был предоставить серверу с моим открытым ключом?

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

Но чтобы ответить на ваш вопрос: да, все, что вы отправляете и получаете (в этом контексте), зашифровано. В случае duckduckgo.comвы общаетесь с общедоступным веб-сервером, чей сертификат SSL проверен, поэтому все должно быть в порядке.

Смотрите также этот ответ для краткого обзора того, как на самом деле работают центры сертификации и SSL.

Другие вопросы по тегам