Carga de un archivo a través de SSL con Client Side Certificate y HttpsURLConnection de Android
Estoy intentando subir un archivo a un servicio web que está protegido con SSL y requiere un certificado del lado del cliente (firmado por una CA interna). La comunicación con el servicio web funciona bien (descargar archivos, consultar, ejecutar comandos y realizar todo tipo de POST funciona bien como se esperaba), excepto para cargar archivos .
Cuando subo archivos obtengo una SSLException (javax.net.ssl.SSLException) que dice "Error de escritura: ssl = 0x5fe209c0: Error de E / S durante la llamada al sistema, Conexión restablecida por peer".
- Verificar manualmente el certificado SSL en WebView
- Certificado de pinning no funciona con OkHttp en Android
- Advertencia de Google Play: controlador WebViewClient.onReceivedSslError
- Alerta de seguridad de Android WebView SSL
- HttpsURLconnection para publicar y obtener en Android
He creado un servidor duplicado y he eliminado los requisitos SSL y Client-Certificate, y he intentado cargar sobre HTTP 'vainilla', y funciona perfectamente.
He intentado usar setFixedLengthStreamingMode (int) y setChunkedStreamingMode (int) sin éxito. Al usarlos, la excepción se lanza desde el método de write
, y cuando no se utiliza ninguno de ellos, la misma excepción se lanza desde la llamada a getResponseCode()
.
No pude encontrar nada sobre el error en EventVwr
del servidor.
Nuestro otro cliente (cliente de iOS) puede subir archivos allí, así que debe ser algo que yo haga – pero no puedo averiguar qué.
No estoy seguro de cómo depurar este problema más.
Por favor ayuda.
Editar 1
Hemos hecho un montón de esfuerzos de depuración y hemos encontrado que:
- Los archivos pequeños se cargan como se esperaba (44kb es el tamaño del archivo más grande que se cargó correctamente y se cargó en ~ 1200ms).
- No se pudo cargar un archivo de 46 KB. El fallo tomó ~ 2 minutos (134120ms).
Editar 2
Después de lo que vas a leer en las observaciones, ahora tengo Fiddler para jugar bien (Gracias a esta pregunta ). Fiddler consiguió el archivo, pero no tuvo éxito en enviarlo. Las peticiones (primas) se parecen a:
POST https://192.168.2.2/rest/transfer/strong/Upload/Full?Path=%5C20140807_113255_20.jpg&Root=2 HTTP/1.1 SessionToken: 1234 // We use this for session management FileMetadata: {"FileSize":"1315496","FileName":"GrumpyCat.jpg"} Connection: Keep-Alive User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.1.1; GT-N7100 Build/JRO03C) Host: 192.168.2.2 Accept-Encoding: gzip Content-Type: application/x-www-form-urlencoded Content-Length: 1315496 ;odiao;awriorijgoeijoeirj;oedfrvgerg... // The image
La respuesta de Fiddler (también RAW) fue:
HTTP/1.1 504 Fiddler - Send Failure Date: Wed, 20 Aug 2014 17:40:29 GMT Content-Type: text/html; charset=UTF-8 Connection: close Timestamp: 20:40:29.420 [Fiddler] ResendRequest() failed: Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host. < An existing connection was forcibly closed by the remote host
Además, hemos agregado el 'MessageLogging' de WCF y el 'Tracing' detallado. MessageLogging no muestra ninguna pista del mensaje (probablemente se cayó antes de convertirse en un mensaje), pero el rastro mostró esto:
Ahora, antes de decir "ahhh, este es un problema de servidor", tenga en cuenta que los archivos de 44kb tienen éxito en la carga, y nuestra aplicación iOS también es capaz de cargar archivos con éxito.
Esta es la pila de llamadas de la excepción que obtiene el cliente:
E/RestClientUploader(3196): javax.net.ssl.SSLException: Write error: ssl=0x5d94b8b0: I/O error during system call, Connection reset by peer E/RestClientUploader(3196): at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_write(Native Method) E/RestClientUploader(3196): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:693) E/RestClientUploader(3196): at java.io.ByteArrayOutputStream.writeTo(ByteArrayOutputStream.java:231) E/RestClientUploader(3196): at libcore.net.http.ChunkedOutputStream.writeBufferedChunkToSocket(ChunkedOutputStream.java:129) E/RestClientUploader(3196): at libcore.net.http.ChunkedOutputStream.write(ChunkedOutputStream.java:77) E/RestClientUploader(3196): at java.io.DataOutputStream.write(DataOutputStream.java:98) E/RestClientUploader(3196): at com.varonis.datanywhere.communication.RestClientUploader.uploadFileToServer(RestClientUploader.java:151) E/RestClientUploader(3196): at com.varonis.datanywhere.communication.RestClientUploader.uploadFullFile(RestClientUploader.java:67) E/RestClientUploader(3196): at com.varonis.datanywhere.communication.services.FileUploadService.doUpload(FileUploadService.java:128) E/RestClientUploader(3196): at com.varonis.datanywhere.communication.services.FileUploadService.onHandleIntent(FileUploadService.java:98) E/RestClientUploader(3196): at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65) E/RestClientUploader(3196): at android.os.Handler.dispatchMessage(Handler.java:99) E/RestClientUploader(3196): at android.os.Looper.loop(Looper.java:137) E/RestClientUploader(3196): at android.os.HandlerThread.run(HandlerThread.java:60)
- Acceso web automático de Webview de Android al sitio Web de https estableciendo cookies de token
- ¿Cómo resolver el problema "ingrese la contraseña para el almacenamiento de credenciales"?
- HttpsUrlConnection: Ancla de confianza para ruta de certificación no encontrada en 2.3
- CertificateException - OpenSSLX509CertificateFactory $ ParsingException
- Compruebe el método onReceivedSslError () de un WebViewClient si se firma un certificado desde una CA propia auto-firmada
- ¿Cómo puedo establecer SignalR en Android Studio para ignorar los problemas de SSL para el desarrollo
- Intermitente PeerUnverifiedException: No hay certificado de compañero con el cliente de Android
- Problemas con el certificado WSS y SSL en Android
No es una respuesta, más un trabajo alrededor – para su referencia.
Después de golpear nuestras cabezas alrededor de este problema, y haciendo un montón de investigación, nos dimos por vencidos. Hemos abierto este problema con Google e implementado el siguiente trabajo:
Para cargar un archivo, la aplicación obtiene primero un Token de carga a través de un punto final que requiere el certificado de cliente y, a continuación, utiliza este token para cargarlo en un punto final que no requiere el certificado de cliente (pero aún sobre SSL (Https) ).
Sí, es un pequeño incumplimiento de la seguridad, pero tuvimos que hacerlo. Lo hemos protegido todo lo que pudimos …
Prometo actualizar cuando el boleto de Google será actualizado (y esperanzadamente resuelto).
HTH!
Es un poco tarde (ya que ya implementó una solución), pero esto debería resolver el problema: https://stackoverflow.com/a/9224892/1619545
Estamos experimentando el mismo problema, establecer el cliente cert negociar bandera para habilitado parece ser lo único que ayuda hat. Echa un vistazo aquí para saber cómo cambiar la bandera en el cert vinculante:
http://help.sap.com/saphelp_smp305svr/helpdata/es/6f/f0a9b6e1c743d48d1e57235d297c1c/content.htm
- ¿Cómo agregar el indicador de "menú" junto al icono de la aplicación de Barra de Acción?
- Android Drawable: el mapa de bits de repetición de lista de capas no se carga cuando está totalmente cubierto