Reutilización de la conexión SSL con Android HttpClient
Estoy desarrollando un servicio web seguro entre mi auto-implementado proxy web java (que reenvía las solicitudes al servicio web real) y una aplicación para Android.
Hacerlo con las conexiones HTTP estándar (inseguras) funciona perfectamente. Ahora quiero usar una conexión segura (SSL) entre el proxy y el cliente android.
- El ancla de la confianza para la trayectoria del certificado no encontrada al usar sobre 3g pero trabaja muy bien sobre WiFi
- HttpsUrlConnection: Ancla de confianza para ruta de certificación no encontrada en 2.3
- Necesitan ayuda para entender las cadenas de certificados
- SSLHandshakeException Ancla de confianza para ruta de certificación no encontrada Android HTTPS
- Utilizando SSL en android
Esto funciona siempre y cuando instancie un nuevo HttpClient para cada solicitud, que está al lado de desperdiciar recursos extremadamente lento, ya que estoy haciendo un apretón de manos de dos vías para cada solicitud.
Así que estoy tratando de reutilizar el HttpClient para cada solicitud que los resultados de las conexiones seguras en la siguiente excepción
Java.lang.IllegalStateException: Conexión ya abierta. En org.apache.http.impl.conn.AbstractPoolEntry.open (AbstractPoolEntry.java:150) en org.apache.http.impl.conn.AbstractPooledConnAdapter.open (AbstractPooledConnAdapter.java:119) en org.apache.http.impl .client.DefaultRequestDirector.execute (DefaultRequestDirector.java:360) en org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java:555) en org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient .java: 487) en org.apache.http.impl.client.AbstractHttpClient.execute (AbstractHttpClient.java:465)
Cuando cambio mi proxy y el cliente a la comunicación de no-ssl funciona sin ningún problema. ¿Alguien sabe lo que estoy haciendo mal? ¡Muchas gracias por tu ayuda!
Por cierto, el código del servidor es totalmente similar excepto usando SSLServerSocket con certificados cargados en lugar de usar ServerSocket.
Configuración de parámetros de cliente
// Set basic data HttpParams params = new BasicHttpParams(); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(params, "UTF-8"); HttpProtocolParams.setUseExpectContinue(params, true); HttpProtocolParams.setUserAgent(params, "Android app/1.0.0"); // Make pool ConnPerRoute connPerRoute = new ConnPerRouteBean(12); ConnManagerParams.setMaxConnectionsPerRoute(params, connPerRoute); ConnManagerParams.setMaxTotalConnections(params, 20); // Set timeout HttpConnectionParams.setStaleCheckingEnabled(params, false); HttpConnectionParams.setConnectionTimeout(params, connectionTimeoutMillis); HttpConnectionParams.setSoTimeout(params, socketTimeoutMillis); HttpConnectionParams.setSocketBufferSize(params, 8192); // Some client params HttpClientParams.setRedirecting(params, false);
Creación de clientes Http
// load truststore certificate InputStream clientTruststoreIs = context.getResources().openRawResource(R.raw.server); KeyStore trustStore = KeyStore.getInstance("BKS"); trustStore.load(clientTruststoreIs, "server".toCharArray()); // initialize trust manager factory with the read truststore TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(trustStore); // setup client certificate // load client certificate InputStream keyStoreStream = context.getResources().openRawResource(R.raw.client); KeyStore keyStore = KeyStore.getInstance("BKS"); keyStore.load(keyStoreStream, "client".toCharArray()); // initialize key manager factory with the read client // certificate KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keyStore, "client".toCharArray()); // initialize SSLSocketFactory to use the certificates SSLSocketFactory socketFactory = new SSLSocketFactory(SSLSocketFactory.TLS, keyStore, "client", trustStore, null, null); // Register http/s shemas! SchemeRegistry schReg = new SchemeRegistry(); schReg.register(new Scheme("https", socketFactory, port)); ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg); httpClient = new DefaultHttpClient(conMgr, params);
Ejecución de la petición del cliente
HttpResponse response = httpClient.execute(request); HttpEntity entity = response.getEntity(); in = entity.getContent(); String result = convertStreamToString(in); in.close();
- OKhttp: SSLProtocolException: Protocolo de enlace SSL finalizado
- Soporte para WebView de Android onReceivedClientCertRequest
- Android WebView setCertificate emite problemas de SSL
- Android: evitar el olfateo (por ejemplo, con CharlesProxy) de tráfico SSL
- Android cómo cambiar los conjuntos de cifrado SSL predeterminados para WebView HTTPS
- Apache HttpClient en Android produciendo CertPathValidatorException (IssuerName! = SubjectName)
- DownloadManager: entiende la política de reintentos y los códigos de error
- Cómo hacer la solicitud https con certificado SSL en Retrofit
Tengo este mismo problema con Android y HttpClient – sólo parece que se manifiesta cuando se utiliza un certificado de cliente, al igual que usted. Elimine la autenticación del cliente y funciona bien, aún no se ha encontrado una solución.
Editar:
Active la comprobación de conexión obsoleta.
HttpConnectionParams.setStaleCheckingEnabled (parámetros, true);
Arreglado para mí.
¿Está utilizando un gestor de conexión seguro de subprocesos? Si no, ese puede ser el problema si está utilizando el mismo HttpClient en múltiples subprocesos.
Este artículo tiene detalles: http://candrews.integralblue.com/2011/09/best-way-to-use-httpclient-in-android/
- El cambio de tema no funciona en <4.0 como debería
- Android – ListView – llamando al getView () bajo demanda