Crear SSL-Socket en Android con certificado autofirmado
Estoy intentando conectar una aplicación de Android a un servidor habilitado para SSL, que utiliza un certificado autofirmado. Ya he leído docenas de tutoriales y la aplicación está aceptando el certificado y conectándome al servidor, pero nunca obtengo ningún dato.
El código original que utilicé para inicializar el socket es el siguiente:
- Java - ignorar certificado SSL expirado
- Error "No se pudo cargar la biblioteca SSL" en Android con TidHTTP
- SSLProtocolException haciendo una conexión https
- Cómo utilizar archivos .key y .pem para crear un socket SSL en Android?
- Cómo utilizar el SSL con multi entidad en android
//passphrase for keystore char[] keystorePass="password".toCharArray(); //load own keystore (MyApp just holds reference to application context) KeyStore keyStore=KeyStore.getInstance("BKS"); keyStore.load(MyApp.getStaticApplicationContext().getResources().openRawResource(R.raw.keystore),keystorePass); //create a factory TrustManagerFactory trustManagerFactory=TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(keyStore); //get context SSLContext sslContext=SSLContext.getInstance("TLS"); //init context sslContext.init( null, trustManagerFactory.getTrustManagers(), new SecureRandom() ); //create the socket Socket socket=sslContext.getSocketFactory().createSocket("hostname",443); socket.setKeepAlive(true);
Posteriormente, el bucle de ejecución del subproceso del receptor utiliza socket.getInputStream () para acceder al flujo de entrada. Mientras uso una conexión sin cifrar, esto funciona sin ningún problema. Pero la conexión segura no recupera ningún dato del socket. He verificado esto agregando mensajes de registro al bucle de recepción e incluso usé el s_server de OpenSSL para comprobarlo. Recuperé los datos del cliente, pero el cliente nunca recibió nada de lo que le envié.
Como última prueba, traté de abrir una conexión a www.google.com:443 así:
javax.net.SocketFactory fact=SSLSocketFactory.getDefault(); Socket socket=fact.createSocket(_config.getUri().getHost(), _config.getUri().getPort());
Todavía el mismo resultado, la conexión funciona, pero utilizando el InputStream no recibo nada del servidor.
¿Alguien tiene alguna idea?
EDITAR:
Actualmente no estoy autorizado a responder a mi propia pregunta, pero aquí está la respuesta: Bueno, resulta que el problema era el bucle de recepción. Confié en InputStream.available()
para obtener el número de bytes para leer, pero no me di cuenta de que era bastante poco fiable (siempre devuelve 0 para socket SSL). Así que cambié el bucle de recepción para usar el bloqueo read()
.
- Anulación del Administrador de confianza de SSL en Android
- Android kSOAP2 Certificados SSL auto-firmados "Requisitos de seguridad no cumplidos - No hay cabecera de seguridad en el mensaje"
- OkHttp con pinzado de certificado
- Javax.net.ssl.SSLHandshakeException: El host remoto cerró la conexión durante el apretón de manos al insertar filas en bigquery
- ¿Firefox para Android utiliza el almacén de certificados de dispositivos?
- Deshabilitar la comprobación de certificados SSL en la biblioteca de actualización
- Descifrado SSL de la aplicación de Android
- Ahora que SSLSocketFactory está obsoleto en Android, ¿cuál sería la mejor manera de manejar la autenticación de certificados de cliente?
Como se mencionó anteriormente: Resulta que el problema era el bucle de recepción. Confié en InputStream.available()
para obtener el número de bytes para leer, pero no me di cuenta de que era bastante poco fiable (siempre devuelve 0 para socket SSL). Así que cambié el bucle de recepción para usar el bloqueo read()
.
- Actualizar la animación del elemento de menú en ActionBarSherlock
- Cómo obtener el ID de archivo para poder realizar una descarga de un archivo de la API de Google Drive en Android