Volley y HTTPS con certificado auto-firmado (Android)

TEORÍA

Vamos a trabajar con la figura del TrustManager y los pinned certificates de Java que deberías conocer antes de empezar a leer esta entrada.

Volley necesita una fábrica de Sockets SSL (SSLSocketFactory) para generar instancias de sockets seguros que le permitan crear y manejar la conexión HTTPS con el servidor.

Esta fábrica de sockets se le da al RequestQueue de Volley (que debería seguir el patrón singleton tal y como se recomienda en la documentación de Android) para que la use.

Esta fábrica de sockets (SSLSocketFactory) es generada gracias a la figura del TrustManager el cual, grosso modo, almacena las CA’s en las que confía, incluyendo aquellas que le indiquemos desde el código.

Una vez generado un TrustManager que confía en nuestro certificado auto-firmado, dentro de código, se genera una fábrica de Sockets SSL (SSLSocketFactory) que se le pasa a Volley para que, en cada petición HTTPS, éste genere un socket SSL seguro con el servidor.

PRÁCTICA

Sea cual sea el método que hayas elegido para crear el TrustManager, el fin será crear un objeto SSLSocketFactory y dárselo al RequestQueue de Volley para que genere conexiones seguras en cada petición HTTPS.

En el constructor del RequestQueue de Volley, se debe incluir un segundo parámetro, que es un objeto que implementa la interfaz «HttpStack«. Este objeto puede ser «HttpClient» o «HurlStack«; dependiendo de la API de Android usada debéis utilizar un objeto u otro (para la API 9 o superior usa «HurlStack» en otro caso usa «HttpClient«).

Volley.newRequestQueue(<Context>, new HurlStack(null, newSslSocketFactory()));

Como se puede observar, el constructor del HurlStack tiene dos parámetros, el segundo es un objeto de tipo «SSLSocketFactory«, el cuál básicamente generará el socket SSL para la conexión cifrada. Para conseguirlo se crea el método «newSslSocketFactory()» que, usando el TrustManager (en realidad, el TrustManagerFactory que genera el TrustManager deseado), generará el objeto «SSLSocketFactory«.

private SSLSocketFactory newSslSocketFactory() {
  // Obtenemos el TrustManager que tengamos almacenado en memoria
  // TrustManagerFactory tmf;

  // Generar el SSLSocketFactory mediante el TrustManager
  SSLContext context = SSLContext.getInstance("TLS");
  context.init(null, tmf.getTrustManagers(), null);
  return context.getSocketFactory();
}

CONTROLAR ERROR SSL EN VOLLEY

Si se quiere controlar un error con el certificado SSL a la hora de realizar la conexión con el servidor (por ejemplo, nuestro certificado «no coincide» con el recibido por el servidor), en el listener «onErrorResponse» de la petición Volley, se puede reaccionar ante el error si es del tipo NoConnectionError y en su mensaje contiene el substring («javax.net.ssl.SSLHandshakeException«):

private Response.ErrorListener createErrorListener(){
  return new Response.ErrorListener() {
    @Override
    public void onErrorResponse(final VolleyError error) {
      if(error.networkResponse == null
      && error instanceof NoConnectionError
      && error.getMessage().contains("javax.net.ssl.SSLHandshakeException"))
      {
      // Se ha producido un error con el certificado SSL y la conexión ha sido
      // rechazada
      }
      ...
    }
  }
}

Créditos de fuentes externas:

Iconos:

  • Server by Chanut is Industries from the Noun Project

Deja un comentario