2012-03-30 8 views
6

Ho bisogno di lavorare con un socket TCP su TLS per un'app su cui sto lavorando. Ho passato dozzine di esempi e mentre non ho problemi a superare la stretta di mano, non riesco a leggere il flusso di input attraverso qualsiasi mezzo (ho provato molto, incluso readline(), lettura su array di caratteri, ecc.). ogni volta che provo, l'app si blocca in quel punto. Se eseguo il debug, non passa mai alla riga successiva del codice.Esempio SSLEngine Android

In una soluzione tentata, ho deciso di passare a utilizzare un SSLEngine, poiché si suppone che sia la risposta Java 1.5 a java.nio per SSL. Tuttavia, ho trovato un esempio (qui: http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/samples/sslengine/SSLEngineSimpleDemo.java) che è più che un po 'di confusione per me, e non ho avuto successo nell'implementarlo. Quando provo, la chiamata unwrap() restituisce un buffer vuoto, dove so (dall'uso di OpenSSL sulla riga di comando) che il servizio in questione spinge i dati indietro nella pipe.

I suggerimenti sono benvenuti, ho già bruciato troppo tempo su questo. Ecco il codice rilevante:

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

Come aggiornamento, ho anche provato a eseguire il ciclo sulla chiamata unwrap mentre (rslt.getStatus()! = SSLEngineResult.Status.OK) e non è mai stato compilato e lo stato non è mai diventato OK. – Paul

+0

Hai provato a eseguire questo codice in una normale applicazione Java? Questo aiuterebbe almeno a determinare se si tratta di un problema specifico per Android o meno. – elevine

+0

Sì, non penso sia specifico per Android, mi è capitato di farlo in un progetto Android. – Paul

risposta

1

Questa implementazione mancano alcuni pezzi chiave. Vale a dire che l'handshake può rimbalzare tra diversi stati NEED_WRAP, NEED_UNWRAP, NEED_TASK per negoziare una connessione. Ciò significa che non puoi chiamare solo uno e poi l'altro. Avrai bisogno di passare in rassegna gli stati fino al completamento di una stretta di mano.

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

Ora Detto questo, si deve essere consapevoli del SSLEngine su Android is broken. Google consiglia di utilizzare thread e socket di blocco in base a quel thread.

0

unwrap() può produrre un buffer vuoto se ciò che è stato scartato era un messaggio di handshake SSL o di allarme, piuttosto che i dati delle applicazioni. Non ci sono abbastanza informazioni qui per dire di più. Qual è stato lo stato del motore in seguito?

0

beginHandshake non procede l'handshake, è solo usato per informare lo SSLEngine che si desidera eseguire l'handshake per le prossime chiamate di wrap/unwrap. È utile quando vuoi fare un'altra stretta di mano. Per quello iniziale, non è necessario in quanto la prima chiamata di wrap avvierà l'handshake.

Inoltre, è necessario controllare il risultato dei metodi di avvolgimento e scartare per sapere se tutti i dati sono stati codificati correttamente. Può succedere che devi chiamare i metodi più volte per elaborare tutti i dati.

Il seguente collegamento potrebbe aiutare: http://onjava.com/onjava/2004/11/03/ssl-nio.html

O questa domanda: SSL Handshaking Using Self-Signed Certs and SSLEngine (JSSE)

0

Ho scritto qualcosa per rendere più semplice l'uso di SSLEngine. Può essere utilizzato con NIO o per altri casi d'uso. Available here SSLFacade