Sto utilizzando HttpClient su Android per connettersi a https://someUrl.com/somePath. Il problema è che il certificato del sito è per * .someUrl.com, non someUrl.com, quindi ricevo una SSLException. Zoppo sulla parte del sito, sì, ma a meno che non riesca a farlo riparare, sono bloccato. C'è un modo per far sì che HttpClient si rilassi e accetti il certificato?HttpClient Android: il nome host nel certificato non corrisponde a <example.com>! = <*. Esempio.com>
HttpClient Android: il nome host nel certificato non corrisponde a <example.com>! = <*. Esempio.com>
risposta
Questo è il mio (a cura) Soluzione:
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;
}
Ha il vantaggio di non cambiare il comportamento di default a meno che non ci sia un dominio jolly, e in tal caso riconvalida come se il dominio a 2 parti (ad esempio, someUrl.com) fosse parte del certificato, altrimenti l'eccezione originale viene riconsegnata. Ciò significa che i certificati non validi continueranno a fallire.
Se si desidera *.someUrl.com
, sembra che si potrebbe semplicemente dargli www.someUrl.com/somePath
anziché someUrl.com/somePath
.
Nope. www.someUrl.com reindirizza a somerl.com – noah
Suppongo che sia inutile, quindi. Hai davvero bisogno di https? Direi di sì, ma questo renderebbe la vita molto più facile. –
Questa è una grande soluzione temporanea quando il sito NON esegue un reindirizzamento! –
Il BouncyCastle su Android è troppo vecchio e non riconosce il certificato con caratteri jolly.
È possibile scrivere il proprio X509TrustManager per verificare la presenza di caratteri jolly.
oppure è possibile disabilitare del tutto il controllo del certificato se è possibile accettare il rischio. Vedere questa domanda,
In realtà ZZ, se l'OP è corretto sul nome del sito e sulla struttura del certificato, il messaggio di errore è corretto: **. SomeUrl.com * deve corrispondere a www.someUrl.com e any.someUrl. com, ma * not * someUrl.com o this.that.someUrl.com. –
se si utilizza un WebView basta chiamare
webview.clearSslPreferences();
di ignorare errori SSL
Ho provato a utilizzare il precedente, ma a volte ottengo eccezioni di overflow dello stack: il metodo verify() non si arresta mai. Su poche centinaia di migliaia di installazioni, accade circa 80 volte a settimana. Hai riscontrato problemi con questo? – user291701
@ user291701 Ho modificato il codice per provare a risolvere il problema. Direi che il problema è che si finisce per impostare nuovamente il verificatore sulla stessa fabbrica, quindi finisce per delegare a se stesso in qualche modo ... Sentiti libero di modificare la mia risposta se trovi un modo migliore. – noah
In ogni caso, sto affrontando "il server non può servire la richiesta perché il tipo di supporto non è supportato". Non ho idea di quale sia la ragione di ciò. –