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

Android HttpClient - имя хоста в сертификате не соответствует <example.com>!= <*. Example.com>

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

4b9b3361

Ответ 1

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

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) был частью сертификата, в противном случае исходное исключение вызваны повторно. Это означает, что действительно недействительные сертификаты все равно будут терпеть неудачу.

Ответ 2

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

Вы можете написать свой собственный X509TrustManager, чтобы проверить наличие шаблона.

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

Самоподписанный прием SSL на Android

Ответ 3

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

Ответ 4

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

webview.clearSslPreferences();

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