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()
.
Czy właściwe jest posiadanie dwóch wątków, jednego do wysyłania danych, a drugiego do odbierania? – snapfractalpop
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