Я хотел бы установить HTTPS-соединение с сервером, и если я использую не эфемерный обмен ключами DH, я хотел бы знать, каковы параметры для этого соединения. На самом деле, мне все равно, эфемерно это или нет.
Я ищу возможность установить соединение, а затем предупредить, если соединение использует «слабые» параметры DH. Это то, что я могу проверить во время подключения? Или набор параметров DH (или, точнее, длина этих параметров в битах) определяется самим набором шифров?
Например, в ветке сообщества Qualys есть иллюстрация наборов шифров, которые SSLLabs считает «слабыми» (ну, все считают их слабыми... у них просто есть общедоступный инструмент, который жалуется на них): https://community.qualys.com/thread/14821
Они конкретно упоминают, например. TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
, который представляет собой набор шифров 0x9f, и укажите параметры DH. Параметры этих параметров встроены в набор шифров (то есть они всегда 1024-битные) или это конфигурация сервера, которая делает эти наборы шифров слабыми из-за выбора конкретного параметра DH?
В любом случае, я хотел бы иметь возможность прослушивать эту информацию из соединения, если это вообще возможно. Кто-нибудь знает, можно ли это сделать и как?
Я написал некоторый код, чтобы попытаться получить эту информацию о рукопожатии, но я продолжаю получать null
для объекта, который, как я надеялся, будет содержать эти данные.
SSLSocketFactory sf = ...;
Socket sock = new Socket();
sock.connect(address, timeout);
SSLSocket socket = (SSLSocket)sf.createSocket(sock, host, port, true);
socket.startHandshake();
SSLSession sess = socket.getHandshakeSession();
Я надеялся, что sess
в этот момент будет содержать какую-то интересную информацию о рукопожатии, но это null
. В javadoc для startHandshake
указано, что он уведомит прослушиватель событий о завершении рукопожатия. Итак, я попробовал это:
SSLSocketFactory sf = ...;
Socket sock = new Socket();
sock.connect(address, timeout);
SSLSocket socket = (SSLSocket)sf.createSocket(sock, host, port, true);
socket.startHandshake();
// SSLSession sess = socket.getHandshakeSession();
SSLSession sess = socket.getSession(); // This forces the handshake to complete
sess = socket.getHandshakeSession();
... но sess
все еще null
на данный момент. «Настоящая» SSLSession действительно существует и дает мне информацию о соединении, но «сеанс рукопожатия», кажется, всегда null
.
Итак, я попытался написать HandshakeCompletedListener
, и на самом деле я получил SSLSession
, но похоже, что это то же самое, что я уже могу получить от SSLSocket
, поэтому сеанс "рукопожатия" кажется бесполезным.
Как я могу получить эти параметры из SSLSession
?
.getHandshakeSession()
работает только во время рукопожатия; после этого результаты находятся в.getSession()
, как вы нашли.SSLSession
содержит сертификат однорангового узла и, таким образом, содержит или будет содержать ключ static-DH, который, как говорит Маартен, никто не использует; эфемерный ключ DH по определению не сертифицирован и не сохраняется в файлеSSLSession
. - person dave_thompson_085   schedule 03.01.2017jdk.tls.disabledAlgorithms
, установленным в коде, илиJRE/lib/security/java.security
q.v. для док. Это (намного?!) менее удобно для пользователей, конечно. - person dave_thompson_085   schedule 03.01.2017