Я использую HttpClient на Android для подключения к https://someUrl.com/somePath. Проблема в том, что сертификат сайта для *.someUrl.com, а не someUrl.com, поэтому я получаю SSLException. Хватит со стороны сайта, да, но если я не смогу это исправить, я застрял. Есть ли способ заставить HttpClient расслабиться и принять сертификат?
Android HttpClient - имя хоста в сертификате не соответствует <example.com>!= <*. Example.com>
Ответ 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, чтобы проверить наличие шаблона.
или вы можете полностью отключить проверку сертификата, если можете принять риск. См. Этот вопрос,
Ответ 3
Если он хочет *.someUrl.com
, то кажется, что вы можете просто дать ему www.someUrl.com/somePath
вместо someUrl.com/somePath
.
Ответ 4
если вы используете WebView, просто вызывайте
webview.clearSslPreferences();
игнорировать ошибки SSL