2012-03-30 13 views
6

Necesito trabajar con un socket TCP sobre TLS para una aplicación en la que estoy trabajando. He pasado por docenas de ejemplos y aunque no tengo problemas para obtener el protocolo de enlace, parece que no puedo leer el flujo de entrada por ningún medio (intenté mucho, incluyendo readline(), lectura a matriz de caracteres, etc.). cada vez que lo intento, la aplicación se congela en ese punto. Si depuro, nunca pasa a la siguiente línea de código.Ejemplo de Android SSLEngine

En un intento de solución, decidí pasar a usar un SSLEngine, ya que se supone que es la respuesta de Java 1.5 a java.nio para SSL. Sin embargo, he encontrado uno ejemplo (aquí: http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/samples/sslengine/SSLEngineSimpleDemo.java) que es más que un poco confuso para mí, y no he tenido éxito en su implementación. Cuando lo intento, la llamada desenvolver() produce un buffer vacío, donde sé (usando OpenSSL en la línea de comandos) que el servicio en cuestión empuja los datos hacia abajo por la tubería.

Sugerencias son bienvenidas, ya me he quemado demasiado tiempo en esto. Aquí está el código correspondiente:

SSLEngine engine = sslContext.createSSLEngine(uri.getHost(), uri.getPort()); 
      engine.setUseClientMode(true); 
      engine.beginHandshake(); 
      SSLSession session = engine.getSession(); 
      int bufferMax = session.getPacketBufferSize(); 
      int appBufferMax = session.getApplicationBufferSize() + 50; 
      ByteBuffer cTo = ByteBuffer.allocateDirect(bufferMax); 
      ByteBuffer sTo = ByteBuffer.allocateDirect(bufferMax); 

      ByteBuffer out = ByteBuffer.wrap(sessionId.getBytes()); 
      ByteBuffer in = ByteBuffer.allocate(appBufferMax); 


      debug("sending secret"); 
      SSLEngineResult rslt = engine.wrap(out, cTo); 
      debug("first result: " + rslt.toString()); 
      sTo.flip(); 
      rslt = engine.unwrap(sTo, in); 
      debug("next result" + rslt.toString()); 
+0

Como una actualización, también probé bucles en la llamada de desencaje mientras (rslt.getStatus()! = SSLEngineResult.Status.OK), y nunca se llenó, y el estado nunca se convirtió en OK. – Paul

+0

¿Ha intentado ejecutar este código en una aplicación Java normal? Eso al menos ayudaría a determinar si es un problema específico de Android o no. – elevine

+0

Sí, no creo que sea específico de Android, simplemente lo estoy haciendo en un proyecto de Android. – Paul

Respuesta

1

Esta aplicación le faltan algunas piezas clave. A saber, el saludo de mano puede rebotar entre varios estados NEED_WRAP, NEED_UNWRAP, NEED_TASK para negociar una conexión. Esto significa que no puedes simplemente llamar a uno y luego al otro. Tendrá que pasar por los estados hasta que se haya completado un apretón de manos.

while (handshaking) { 
     switch (state) { 
      case NEED_WRAP: 
       doWrap(); 
       break; 
      case NEED_UNWRAP: 
       doUnwrap(); 
       break; 
      case NEED_TASK: 
       doTask(); 
       break; 
     } 
    } 

A full working example of Java SSL and NIO

Ahora dicho esto, debe tener en cuenta la SSLEngine en Android is broken. Google recomienda usar subprocesos y sockets de bloqueo de acuerdo con ese hilo.

0

unwrap() puede producir un buffer vacío si lo que se desenvolvió era un mensaje de SSL apretón de manos o de alerta, en lugar de datos de la aplicación. No hay suficiente información aquí para decir más. ¿Cuál fue el estado del motor después?

0

beginHandshake no procede el saludo de mano, solo se utiliza para informar al SSLEngine que desea realizar el intercambio de información para que las próximas llamadas se envuelvan/desenrollen. Es útil cuando quieres hacer otro apretón de manos. Para la inicial, no es necesaria ya que la primera llamada para envolver iniciará el intercambio de información.

Además, debe verificar el resultado de los métodos de ajuste y desenvoltura para saber si todos los datos se han codificado correctamente. Puede suceder que tenga que llamar a los métodos varias veces para procesar todos los datos.

En el siguiente enlace puede ayudar: http://onjava.com/onjava/2004/11/03/ssl-nio.html

O esta pregunta: SSL Handshaking Using Self-Signed Certs and SSLEngine (JSSE)

Cuestiones relacionadas