java - para - Android HttpClient: el nombre de host en el certificado no coincide con<ejemplo.com>!=<*. Ejemplo.com>
pinning android (4)
Si quiere *.someUrl.com
, entonces parece que podría simplemente darle www.someUrl.com/somePath
lugar de someUrl.com/somePath
.
Estoy usando HttpClient en Android para conectarme a https://someUrl.com/somePath . El problema es que el certificado del sitio es para * .someUrl.com, no para someUrl.com, así que obtengo una SSLException. Cojo por parte del sitio, sí, pero a menos que pueda arreglarlo, estoy atascado. ¿Hay alguna manera de hacer que HttpClient se relaje y acepte el certificado?
Esta es mi solución (editada):
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;
}
Tiene la ventaja de no cambiar el comportamiento predeterminado a menos que exista un dominio comodín, y en ese caso se revalida como si el dominio de 2 partes (por ejemplo, someUrl.com) fuera parte del certificado, de lo contrario se vuelve a lanzar la excepción original. Eso significa que los certs verdaderamente inválidos seguirán fallando.
si usa un WebView simplemente llame
webview.clearSslPreferences();
ignorar los errores de SSL
El BouncyCastle en Android es demasiado viejo y no reconoce el certificado comodín.
Puede escribir su propio X509TrustManager para buscar comodines.
o puede deshabilitar la verificación del certificado por completo si puede aceptar el riesgo. Mira esta pregunta