OkHttp 2.0 вручную проверяет используемый набор шифров

Я пытаюсь найти способ проверить Cipher Suite (CS), который был выбран во время рукопожатия TLS. Я хочу иметь возможность вручную отключить рукопожатие или, по крайней мере, остановить отправку тела http-сообщения, если CS не пройдет какую-либо ручную проверку.

Я запрашиваю подмножество CS, используя пользовательский SocketFactory, но это не всегда соблюдается сервером.

Я играл с этим внутри обратного вызова HandshakeCompletedListener, но это оказалось сложно. Выброс любого класса RuntimeException ничего не сделает из-за перехвата всех в вызывающем методе. Закрытие сокета также не будет иметь никакого значения, что, как я думал, может вызвать внутреннее исключение, что в любом случае не будет отличным решением.

Любая помощь будет здорово.

EDIT: после ответа @jesse-wilsons ниже я использую 2.1-RC1 и класс ConnectionSpec, чтобы указать, какие наборы шифров (CS) я хочу использовать, однако бывают случаи, когда существующий сеанс SSL может быть повторно используется с другим набором шифров. Я включил пользовательский HostNameVerifier, чтобы отловить любые случаи, когда SSL-соединение пытается установить с другим, чем запрошенный CS. Это немного похоже на обувной рожок, но я не вижу другого способа подключиться после того, как произошло рукопожатие SSL.

public class HostnameAndCipherSuiteVerifier implements HostnameVerifier
{
    private final String mHostname, mCipherSuite;

    public HostnameAndCipherSuiteVerifier(String hostname, String cipherSuite)
    {
        mHostname = hostname;
        mCipherSuite = cipherSuite;
    }

    @Override
    public boolean verify(String hostname, SSLSession session)
    {
        //delegate to original hostname verifier
        if(!OkHostnameVerifier.INSTANCE.verify(hostname, session))
        {
            XLog.w("delegate hostname check failed");
            return false;
        }

        //hardcode check for domain
        if(!hostname.equals(mHostname))
        {
            XLog.w("Hard-coding hostname fail");
            return false;
        }

        //handshake cipher check
        if(!session.getCipherSuite().equals(mCipherSuite))
        {
            XLog.w("cipher check failed");
            return false;
        }
        else
            return true;
    }
}

person Dori    schedule 06.11.2014    source источник


Ответы (1)


Возьмите OkHttp 2.1-RC1 и используйте новый класс ConnectionSpec, чтобы ограничить наборы шифров теми, которые вам нравятся.

person Jesse Wilson    schedule 06.11.2014
comment
Это круто, спасибо - лучший способ указать запрошенный CS. Однако это не гарантирует, что будут приняты только эти CS. Обновлю свой ответ выше текущим решением, которое я использую для принудительного выбора CS - было бы здорово, если бы вы могли сказать мне, есть ли более простой способ или вызовет ли вышеуказанный подход какие-либо проблемы. Спасибо :) - person Dori; 11.11.2014