Создание SSL-сокета на Android с самозаверяющим сертификатом

Я пытаюсь подключить приложение 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 () для доступа к входному потоку. Пока я использую незашифрованное соединение, это работает без проблем. Но безопасное соединение не извлекает никаких данных из сокета. Я проверил это, добавив сообщения журнала в цикл приема и даже использовал для проверки s_server OpenSSL. Я получил данные от клиента, но клиент так и не получил ничего, что я ему отправил.

В качестве последнего теста я попытался открыть соединение с www.google.com:443 следующим образом:

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

По-прежнему тот же результат, соединение работает, но с использованием InputStream я ничего не получаю от сервера.

У кого-нибудь есть идеи?

РЕДАКТИРОВАТЬ:

В настоящее время мне не разрешено отвечать на свой вопрос, но вот ответ: Что ж, оказывается, проблема заключалась в петле приема. Я полагался на InputStream.available () , чтобы получить количество байтов для чтения, но не понимал, что это ненадежно (всегда возвращает 0 для сокета SSL).Поэтому я переключил цикл приема на использование блокировки read () .

11
задан mistalee 2 January 2012 в 09:33
поделиться