Подтвердить что ты не робот

HTTPS GET (SSL) с Android и самозаверяющим сертификатом сервера

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

javax.net.ssl.SSLException: сообщение сертификата несертифицированного сервера.

Невозможно изменить сервер, чтобы иметь доверенный сертификат, а также не может сделать сертификат сервера соответствующим IP-адресу сервера.

Обратите внимание, что сервер не будет иметь DNS-имя, оно будет иметь только IP-адрес. Запрос GET выглядит примерно так:

 https://username:[email protected]/blabla/index.php?param=1&param2=3

Я полностью понимаю, что это решение подвержено атакам типа "человек-в-середине" и т.д.

Итак, решение должно игнорировать отсутствие доверия к сертификату и игнорировать несоответствие имени хоста.

Кто-нибудь знает код, который делает это, используя Java для Android?

Есть много попыток объяснить это на stackoverflow.com и множество фрагментов кода, но они, похоже, не работают, и никто не предоставил один блок кода, который решает это, насколько я вижу. Было бы интересно узнать, действительно ли кто-то решил это, или если Android просто блокирует сертификаты, которым не доверяют.

4b9b3361

Ответ 1

Я сделал приложение, которое использует самоподписанные или доверяет всем сертификатам. Источник находится здесь: http://code.google.com/p/meneameandroid/source/browse/#svn/trunk/src/com/dcg/auth и может свободно использоваться: P

Просто используйте HttpManager и создайте SSL factory, используя доверие всего: http://code.google.com/p/meneameandroid/source/browse/trunk/src/com/dcg/util/HttpManager.java

EDIT: обновленные ссылки

Ответ 2

Как вы правильно отметили, есть две проблемы: a) сертификат не доверен, и b) имя в сертификате не совпадает с именем хоста.

ПРЕДУПРЕЖДЕНИЕ: для любого другого, кто приходит к этому ответу, это грязный, ужасный взлом, и вы не должны использовать его для чего-либо, что имеет значение. SSL/TLS без аутентификации хуже, чем отсутствие шифрования - чтение и изменение ваших "зашифрованных" данных - это тривиальный для злоумышленника, и вы даже не знали, что это происходит.

Еще со мной? Я боялся так...

a) решается путем создания настраиваемого SSLContext, TrustManager которого принимает что-либо:

SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, new TrustManager[] {
  new X509TrustManager() {
    public void checkClientTrusted(X509Certificate[] chain, String authType) {}
    public void checkServerTrusted(X509Certificate[] chain, String authType) {}
    public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[]{}; }
  }
}, null);
HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());

и b), создав HostnameVerifier, который позволяет продолжить соединение, даже если сертификат не соответствует имени хоста:

HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
  public boolean verify(String hostname, SSLSession session) {
    return true;
  }
});

Оба должны произойти прямо в начале вашего кода, прежде чем вы начнете возиться с HttpsURLConnections и так далее. Это работает как в Android, так и в обычной JRE. Наслаждайтесь.

Ответ 3

Если вы используете HttpsURLConnection, попробуйте позвонить setHostnameVerifier на нем перед connect() и передать ему HostnameVerifier, который просто принимает независимо от правдоподобия.

Ответ 5

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

С другой стороны, вы можете использовать этот метод, но я считаю это своего рода уродливым.


Ресурсы:

В той же теме:

Ответ 6

Если вы спросите меня, сделайте это безопасным способом.

Нашел хороший учебник http://blog.antoine.li/index.php/2010/10/android-trusting-ssl-certificates/, и это действительно не так сложно реализовать.

Также рекомендуется учебник, рекомендованный Maciek.

Я тестировал его, и он работает в моем приложении без проблем.

Ответ 7

Я сделал приложение, которое использует самоподписанный сертификат 4 месяца назад, вот код, на который я надеюсь: https://bitbucket.org/momo0002/tlsdemo.git