Aceptar certificados SSL autofirmados-> donde configurar TrustManager predeterminado

Primero tuve que admitir que sé que aceptar todos los certificados puede ser considerado como sin seguridad. Tenemos Certs "reales" pero solamente en nuestros sistemas vivos. Los certificados en nuestros sistemas de prueba son auto-firmados. Así que mientras nos estamos desarrollando, tenemos que usar servidores de prueba, lo que me obliga a deshabilitar certificados.

Vi un montón de toppics aquí en Stackoverflow y en toda la web que están todos tratando de hacer lo mismo: Aceptación de certificados SSL. Sin embargo, ninguna de estas respuestas parece aplicarse a mi problema, ya que no estoy jugando con HTTPSUrlConnections .

Si estoy haciendo una solicitud el código normalmente se parece a esto (comentado para la clarificación):

 //creates an HTTP-Post with an URL HttpPost post = createBaseHttpPost(); //loads the request Data inside the httpPost post.setEntity(getHttpPostEntity()); //appends some Headers like user-agend or Request UUIDs appendHeaders(post); HttpClient client = new DefaultHttpClient(); //mResponse is a custom Object which is returned //from the custom ResponseHandler(mResponseHandler) mResponse = client.execute(post, mResponseHandler); return mResponse; 

Leí que debo inyectar mi propio TrustManager y X509HostnameVerivier . Los he creado así:

 private static final TrustManager[] TRUST_ALL_CERTS = new TrustManager[]{ new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[]{}; } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } } }; private static X509HostnameVerifier ACCEPT_ALL_HOSTNAMES = new X509HostnameVerifier() { public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException { } public void verify(String host, X509Certificate cert) throws SSLException { } public void verify(String host, SSLSocket ssl) throws IOException { } public boolean verify(String host, SSLSession session) { return true; } }; 

Si me inyecto HostnameVerifier dentro de mi solicitud como esta (el cliente es DefaultHttpClient desde arriba)

 SSLSocketFactory ssl = (SSLSocketFactory)client.getConnectionManager().getSchemeRegistry().getScheme("https").getSocketFactory(); ssl.setHostnameVerifier(ACCEPT_ALL_HOSTNAMES); 

La respuesta cambia de "hostname ** no coinciden" a "Bad request". Supongo que tengo que configurar el TrustManager, pero no tengo ni idea de dónde establecerlo dentro de mi solicitud, ya que no estoy usando HttpsUrlConnections mencionado en todas partes que lo busqué.

No, no te obliga a deshabilitar la validación, te obliga a implementar la validación correctamente. No acepte ciegamente todos los certificados. Y no, su caso no es diferente, sólo tiene que confiar en un certificado que Android no confía por defecto.

Está utilizando HttpClient, por lo que las API para configurar el administrador de confianza son algo diferentes de HttpsURLConnection , pero el procedimiento es el mismo:

  1. Cargue un archivo de almacén de claves con certificados de confianza (los certificados autofirmados del servidor)
  2. Inicializar un KeyStore con él.
  3. Cree un SocketFactory usando el KeyStore de 2.
  4. Establezca su biblioteca de cliente HTTP para usarla cuando cree sockets SSL.

Esto se describe en la documentación de Android: http://developer.android.com/reference/org/apache/http/conn/ssl/SSLSocketFactory.html

Un artículo más detallado sobre el tema, muestra cómo crear el archivo de almacén de confianza: http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html

Algunos antecedentes y código de ejemplo: http://nelenkov.blogspot.com/2011/12/using-custom-certificate-trust-store-on.html

Este es el código que necesita para inicializar HttpClient:

 KeyStore localTrustStore = KeyStore.getInstance("BKS"); InputStream in = getResources().openRawResource(R.raw.mytruststore); localTrustStore.load(in, TRUSTSTORE_PASSWORD.toCharArray()); SchemeRegistry schemeRegistry = new SchemeRegistry(); schemeRegistry.register(new Scheme("http", PlainSocketFactory .getSocketFactory(), 80)); SSLSocketFactory sslSocketFactory = new SSLSocketFactory(localTrustStore); schemeRegistry.register(new Scheme("https", sslSocketFactory, 443)); HttpParams params = new BasicHttpParams(); ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry); HttpClient client = new DefaultHttpClient(cm, params); 

En este punto, no tienes excusas para confiar en todos los certificados. Si lo haces, todo en ti 🙂

  • Org.apache.http.client.ClientProtocolException
  • ¿No pudo validar la firma del certificado?
  • cómo instalar el certificado de CA mediante programación en Android sin interacción del usuario
  • Instalar certificado de usuario a través de ADB
  • Instalar certificado X509 mediante programación en mi caso
  • Android - ¿Hay una manera de obtener platform.pk8 y platform.x509.pem la ROM firmada con?
  • Agregar información de certificados de servidor a Trust Manager Android mediante programación
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.