Android ssl: javax.net.ssl.SSLPeerUnverifiedException: Ningún certificado de igual (una vez más)
Tengo un sitio web que estoy habilitando ssl para un servicio RESTful. Nos hemos registrado con RapidSSL, instalado los certs, y pasa el comprobador de RapidSSL . Soy capaz de acceder al sitio con varios navegadores, incluyendo los navegadores android (construido en, firefox y ópera) sin problemas, sin advertencias.
Sin embargo, cuando intento acceder a él con mi aplicación de Android, obtengo la siguiente excepción:
- javax.net.ssl.SSLException con Facebook SDK, Android
- ¿El Apache DefaultHttpClient (Android) y NSURLConnection (iOS) vuelven a intentar las conexiones fallidas con versiones de protocolo anteriores?
- "Flujo no representa una tienda de claves PKCS12" después de almacenar con una nueva contraseña en el dispositivo Android
- Android - Error al conectar con URI de inicio de sesión
- ¿Cómo se puede cargar https url sin el uso de ssl en android webview
08-11 20:04:05.586 363 381 E HttpProvider: Error executing request: No peer certificate 08-11 20:04:05.586 363 381 E HttpProvider: javax.net.ssl.SSLPeerUnverifiedException: No peer certificate 08-11 20:04:05.586 363 381 E HttpProvider: at org.apache.harmony.xnet.provider.jsse.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:259) 08-11 20:04:05.586 363 381 E HttpProvider: at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:93) 08-11 20:04:05.586 363 381 E HttpProvider: at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:381) 08-11 20:04:05.586 363 381 E HttpProvider: at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:164) 08-11 20:04:05.586 363 381 E HttpProvider: at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) 08-11 20:04:05.586 363 381 E HttpProvider: at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) 08-11 20:04:05.586 363 381 E HttpProvider: at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:359) 08-11 20:04:05.586 363 381 E HttpProvider: at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 08-11 20:04:05.586 363 381 E HttpProvider: at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 08-11 20:04:05.586 363 381 E HttpProvider: at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) 08-11 20:04:05.586 363 381 E HttpProvider: at com.xxxxx.netlib.http.HttpProvider.executeRequest(HttpProvider.java:75)
Esto ocurre en android 2.3.3 en el emulador y en una tableta 3.2. He visto muchos hits en esto, pero nada de lo que he encontrado me ayuda a solucionar el problema.
Más datos:
$ openssl s_client -CAfile www.xxxxx.com.pem -connect www.xxxxx.com:443 CONNECTED(00000003) depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority verify return:1 depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA verify return:1 depth=1 C = US, O = "GeoTrust, Inc.", CN = RapidSSL CA verify return:1 depth=0 serialNumber = 1-7wArtEjdTwJ94d5iVDooDmmC4mXyVj, OU = GT82425783, OU = See www.rapidssl.com/resources/cps (c)12, OU = Domain Control Validated - RapidSSL(R), CN = www.xxxxx.com verify return:1 --- Certificate chain 0 s:/serialNumber=1-7wArtEjdTwJ94d5iVDooDmmC4mXyVj/OU=GT82425783/OU=See www.rapidssl.com/resources/cps (c)12/OU=Domain Control Validated - RapidSSL(R)/CN=www.xxxxx.com i:/C=US/O=GeoTrust, Inc./CN=RapidSSL CA 1 s:/C=US/O=GeoTrust, Inc./CN=RapidSSL CA i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA 2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority --- [snip]
El código que estoy corriendo para configurar el cliente:
public class HttpProvider implements INetworkProvider { private static final String LOG = "HttpProvider"; protected DefaultHttpClient client; public HttpProvider() { SchemeRegistry registry = new SchemeRegistry(); registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); final SSLSocketFactory sslSocketFactory = SSLSocketFactory.getSocketFactory(); sslSocketFactory.setHostnameVerifier(SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); registry.register(new Scheme("https", sslSocketFactory, 443)); client = new DefaultHttpClient( new ThreadSafeClientConnManager((new BasicHttpParams()), registry), new BasicHttpParams() ); } [snip]
También he intentado con STRICT_HOSTNAME_VERIFIER y todavía no disfruto.
Por lo que entiendo que no debería tener que configurar truststores o almacenes de llaves personalizados ya que estoy registrado con un proveedor de CERT reconocido.
Soy muy nuevo con ssl y encuentro que estoy nadando en un mar de acrónimos de tres letras, y yo estaba esperando que alguien aquí puede ser capaz de darme un empujón en la dirección correcta.
- Android se conecta al servidor con certificado autenticado
- Error de SSL durante el inicio de sesión de Facebook en Android
- ¿Cómo conectar un socket SSL a través de un proxy HTTP?
- Certificados WebView y SSL
- Error de certificado no confiable y httpclient en android
- Error "No se pudo cargar la biblioteca SSL" en Android con TidHTTP
- Certificado de fijación en Android
- OkHttp javax.net.ssl.SSLPeerUnverifiedException: Nombre de host domain.com no verificado
Después de montones de excavación y experimentación, finalmente me di cuenta de que la url que estaba usando tenía codificado el puerto 80 en lugar de fallar a 443. Mudo tonto mudo.
La respuesta a esta pregunta Confiar en todos los certificados que utilizan HttpClient a través de HTTPS ayudó tremendamente a mi comprensión de SSL.
- Mostrar fragmento como un diálogo o como una actividad habitual
- No se puede depurar la aplicación en el dispositivo Android – Android Studio 2.0