Я пытаюсь подключить Android-приложение к серверу с поддержкой SSL, который использует самозаверяющий сертификат. Я уже читал десятки уроков, и приложение теперь принимает сертификат и подключается к серверу, но я никогда не получаю никаких данных.
Исходный код, который я использовал для инициализации сокета, таков:
//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);
Затем в цикле выполнения потока получателя используется socket.getInputStream() для доступа к входному потоку. Пока я использую незашифрованное соединение, это работает без проблем. Но безопасное соединение не извлекает любые данные из сокета. Я проверил это, добавив сообщения журнала в цикл получения и даже использовал OpenSSL s_server для проверки. Я получил данные от клиента, но клиент никогда не получал ничего, что я ему отправил.
В качестве последнего теста я попытался открыть соединение с www.google.com:443 следующим образом:
javax.net.SocketFactory fact=SSLSocketFactory.getDefault();
Socket socket=fact.createSocket(_config.getUri().getHost(), _config.getUri().getPort());
По-прежнему тот же результат, соединение работает, но с использованием InputStream я ничего не получаю от сервера.
У кого-нибудь есть идеи?
EDIT:
В настоящее время мне не разрешают отвечать на свой вопрос, но вот ответ:
Ну, получается проблема WAS loop. Я полагался на InputStream.available()
, чтобы получить количество прочитанных байтов, но не понял, что он был ненадежным (всегда возвращает 0 для сокета SSL). Поэтому я переключил цикл приема, чтобы вместо этого использовать блокировку read()
.