Пользовательская обработка SSL перестала работать на Android 2.2 FroYo

Для моего приложения Transdroid я подключаюсь к удаленным серверам через HTTP и, при необходимости, через HTTPS. Для этих HTTPS-соединений с HttpClient я использую собственную реализацию фабрики сокетов SSL, чтобы убедиться, что работают самоподписанные сертификаты. По сути, я принимаю все и игнорирую каждую проверку любого сертификата.

Некоторое время это работало нормально, но больше не работает на Android 2.2 FroYo. При попытке подключения он выдаст исключение:

java.io.IOException: SSL handshake failure: I/O error during system call, Broken pipe

Вот как я инициализирую HttpClient:

    SchemeRegistry registry = new SchemeRegistry();
    registry.register(new Scheme("http", new PlainSocketFactory(), 80));
    registry.register(new Scheme("https", (trustAll ? new FakeSocketFactory() : SSLSocketFactory.getSocketFactory()), 443));
    client = new DefaultHttpClient(new ThreadSafeClientConnManager(httpParams, registry), httpParams);

Я использую FakeSocketFactory и FakeTrustManager, источник которых можно найти здесь.

Опять же, я не понимаю, почему это внезапно перестало работать, или даже что означает ошибка "Сломанная труба". В Твиттере я видел сообщения о том, что Seesmic и Twidroid не работают с включенным SSL и на FroYo, но я не уверен, связано ли это.

Спасибо за любые указания / помощь!

2 ответа

Решение

Вот ответ, во многом благодаря полезному разработчику Seesmic, готовому поделиться этим исправлением:

В фабрике пользовательских сокетов, создание сокетов (с createSocket) видимо был изменен специально для SSLSocketFactory реализация. Итак старый

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
                    throws IOException, UnknownHostException {
            return getSSLContext().getSocketFactory().createSocket();
    }

Необходимо изменить на:

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
                    throws IOException, UnknownHostException {
            return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
    }

И тогда это снова сработало для меня!

ОБНОВЛЕНИЕ: Поскольку это все еще популярный ответ, позвольте мне обновить мою ссылку на рабочий код. Эта фабрика сокетов с поддержкой SSl, которая поддерживает современные протоколы (TLS 1.1+), SNI и дополнительно позволяет принимать все сертификаты (небезопасные, игнорирует все сертификаты SSL) или самозаверяющие сертификаты (с помощью хэша SHA-1).

Подробнее об этой проблеме http://code.google.com/p/android/issues/detail?id=10472 Это исправило проблему SSL, которая возникла у нас в HTC Desire при обновлении до Android 2.2.

Другие вопросы по тегам