2012-01-02 16 views
10

Próbuję połączyć aplikację na Androida z serwerem obsługującym SSL, który korzysta z samopodpisanego certyfikatu. Przeczytałem już kilkadziesiąt samouczków, a aplikacja akceptuje teraz połączenie z serwerem, ale nigdy nie otrzymuję żadnych danych.Utwórz protokół SSL-Socket na urządzeniu z systemem Android z samopodpisanym certyfikatem

Oryginalny kod i inicjalizowania gniazdo to:

//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); 

Następnie pętla przebieg nici odbiornik wykorzystuje socket.getInputStream() dostęp do strumienia wejściowego. Dopóki używam nieszyfrowanego połączenia, działa to bez problemu. Ale bezpieczne połączenie nie pobiera żadnych danych z gniazdka. Zweryfikowałem to przez dodanie komunikatów dziennika do pętli odbiorczej, a nawet użycie serwera s_ OpenSSL do sprawdzenia. Pobrałem dane od klienta, ale klient nigdy nie otrzymał niczego, co do niego wysłałem.

W ostatnim teście, próbowałem otworzyć połączenie do www.google.com:443 tak:

javax.net.SocketFactory fact=SSLSocketFactory.getDefault(); 
Socket socket=fact.createSocket(_config.getUri().getHost(), _config.getUri().getPort()); 

Wciąż ten sam wynik, ale prac przyłączeniowych pomocą InputStream otrzymam nic z serwera .

Ktoś ma jakieś pomysły?

EDIT:

Jestem obecnie niedozwolone odpowiedzieć na moje własne pytanie, ale tutaj jest odpowiedź: Cóż, okazuje się, że problem został pętla otrzymać. Opierałem się na InputStream.available(), aby uzyskać liczbę bajtów do odczytu, ale nie zdawałem sobie sprawy, że było to raczej niewiarygodne (zawsze zwraca 0 dla gniazda SSL). Więc zamiast tego zmieniłem pętlę odbioru, aby użyć blokowania read().

Odpowiedz

7

Jak wspomniano powyżej: Wył ± cza problem WAS pętli odbioru. Opierałem się na InputStream.available(), aby uzyskać liczbę bajtów do odczytu, ale nie zdawałem sobie sprawy, że było to raczej niewiarygodne (zawsze zwraca 0 dla gniazda SSL). Więc zamiast tego zmieniłem pętlę odbioru, aby użyć blokowania read().

+0

Czy właściwe jest posiadanie dwóch wątków, jednego do wysyłania danych, a drugiego do odbierania? – snapfractalpop

+2

Tak, moim zdaniem powinieneś używać dwóch wątków, szczególnie jeśli korzystasz z komunikacji w trybie pełnego dupleksu. Przeczytałem też kilka postów, to powinno być dość bezpieczne, ponieważ używasz różnych strumieni do czytania i pisania. – mistalee

Powiązane problemy