Я пытаюсь найти способ проверить 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;
}
}