Android HttpClient - имя хоста в сертификате не совпадает! = <*. example.com> - PullRequest
18 голосов
/ 28 июня 2010

Я использую HttpClient на Android для подключения к https://someUrl.com/somePath. Проблема в том, что сертификат сайта предназначен для * .someUrl.com, а не someUrl.com, поэтому я получаю исключение SSLEx. Да, со стороны сайта, но если я не могу это исправить, я застрял. Есть ли способ заставить HttpClient расслабиться и принять сертификат?

Ответы [ 4 ]

33 голосов
/ 29 июня 2010

Это мое (отредактированное) решение:

class MyVerifier extends AbstractVerifier {

    private final X509HostnameVerifier delegate;

    public MyVerifier(final X509HostnameVerifier delegate) {
        this.delegate = delegate;
    }

    @Override
    public void verify(String host, String[] cns, String[] subjectAlts)
                throws SSLException {
        boolean ok = false;
        try {
            delegate.verify(host, cns, subjectAlts);
        } catch (SSLException e) {
            for (String cn : cns) {
                if (cn.startsWith("*.")) {
                    try {
                          delegate.verify(host, new String[] { 
                                cn.substring(2) }, subjectAlts);
                          ok = true;
                    } catch (Exception e1) { }
                }
            }
            if(!ok) throw e;
        }
    }
}


public DefaultHttpClient getTolerantClient() {
    DefaultHttpClient client = new DefaultHttpClient();
    SSLSocketFactory sslSocketFactory = (SSLSocketFactory) client
            .getConnectionManager().getSchemeRegistry().getScheme("https")
            .getSocketFactory();
    final X509HostnameVerifier delegate = sslSocketFactory.getHostnameVerifier();
    if(!(delegate instanceof MyVerifier)) {
        sslSocketFactory.setHostnameVerifier(new MyVerifier(delegate));
    }
    return client;
}

Преимущество состоит в том, что он не меняет поведение по умолчанию, если не существует подстановочного домена, и в этом случае он переопределяется, как если бы домен из 2 частей (например, someUrl.com) был частью сертификата, в противном случае исходное исключение вызваны повторно. Это означает, что действительно недействительные сертификаты все равно не пройдут.

3 голосов
/ 29 июня 2010

BouncyCastle на Android слишком стар и не распознает подстановочный сертификат.

Вы можете написать свой собственный X509TrustManager для проверки подстановочного знака.

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

Самозаверяющее принятие SSL на Android

1 голос
/ 07 октября 2011

если вы используете WebView, просто позвоните

webview.clearSslPreferences();

, чтобы игнорировать ошибки SSL

1 голос
/ 28 июня 2010

Если он хочет *.someUrl.com, то кажется, что вы могли бы просто дать ему www.someUrl.com/somePath вместо someUrl.com/somePath.

...