2016-06-09 29 views
10

Desidero avere un server TCP crittografato SSL sul dispositivo Android e un client sul computer che si connetterà al dispositivo.SSLSocket si blocca su getInputStream quando il dispositivo Android è in wifi

Creo un SSLServerSocket sul dispositivo Android con un proprio keystore.

final KeyStore localTrustStore = KeyStore.getInstance("BKS"); //NON-NLS 
final InputStream in = context.getResources().openRawResource(R.raw.syncapp); 
localTrustStore.load(in, "secret".toCharArray()); //Keystore pw 
in.close(); 

final SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); //NON-NLS 

final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
trustManagerFactory.init(localTrustStore); 

final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
keyManagerFactory.init(localTrustStore, "secret".toCharArray()); //privat key pw 

sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); 

serverSocket = sslContext.getServerSocketFactory().createServerSocket(SERVER_PORT); 
((SSLServerSocket) serverSocket).setNeedClientAuth(true); 

Quindi attendo che un client si connetta. Quando un cliente vuole collegare un nuovo thread viene avviato e le correnti ottenere chiesto:

final DataInputStream input = new DataInputStream(this.clientSocket.getInputStream()); 
final DataOutputStream output = new DataOutputStream(new BufferedOutputStream(clientSocket.getOutputStream())); 

Prima ho usato questo codice con USB-Tethering per ottenere una connessione tra il computer e il dispositivo Android. Quindi nessuna rete Wifi/rete era abilitata. Tutto ha funzionato perfettamente.

Quindi ho attivato il wifi sul dispositivo Android e connettersi a una WLAN senza Internet. Ma ora la chiamata a getInputStream() sembra richiedere da 5 a 10 secondi. Se disattivo SSL funziona perfettamente. Se la wlan si connette a Internet non c'è nemmeno il ritardo. L'ho provato con Android 4.2 e 5.1. Aggiornamento : Ora potrei provare questo problema con Android 6. E il problema sembra essere risolto lì ...

La stretta di mano è terminata correttamente, ma dopo che sembra esserci una sorta di ritardo sul dispositivo Android. (La chiamata a getInputStream consuma quella volta) Alcuni sviluppatori stanno dicendo che eseguirà una ricerca inversa DNS che verrà eseguita in un timeout.

enter image description here

Date un'occhiata alla cattura, il primo collegamento è stato fatto mentre wifi è stato disattivato. Ci sono voluti 0,3 secondi per effettuare il trasferimento dei dati. Poi ho appena attivato il wifi, non mi sono collegato al wifi, esso comunica ancora tramite usb. E ci sono voluti più di 5 secondi.

Ho trovato il problema anche qui, ma stanno utilizzando un socket client. Ho bisogno di un socket del server. Qualcuno ha qualche idea su come risolvere questo problema?

TLS connection using SSLSocket is slow in Android OS

+0

Non ha alcun senso per utilizzare lo stesso file sia come vendite e la fiducia chiavi. – EJP

+0

Puoi approfondire questo? Ho un keystore per il server con una coppia di chiavi e la chiave pubblica del client. Il client ha la sua coppia di chiavi e la chiave pubblica dal server. Così possono convalidarsi a vicenda ma nessun altro può connettersi con esso. – Rocket

+0

Il trust store è di chi ti fidi. Questo è il tipo di cosa che potrebbe essere decisa da un comitato, potrebbe essere estesa a tutto il sito o a livello aziendale, o addirittura a livello di JDK per impostazione predefinita. Il keystore contiene la propria chiave privata e il certificato firmato. Questi sono ** segreti **. Il regime di sicurezza che li circonda è completamente diverso in ciascun caso. Non ha assolutamente senso usare lo stesso file fisico per entrambi. – EJP

risposta

0

Sei giusto che ci sia una ricerca DNS inversa che è timeout. In determinati ambienti Java Runtime, durante l'handshake con un indirizzo IP non elaborato, SSLContext esegue inutilmente una ricerca dell'indirizzo IP del server. Questo è per determinare se il nome comune del certificato del server corrisponde. Provare a utilizzare una delle soluzioni indicate qui:

How to disable Java's SSL Reverse DNS Lookup