Могу ли я определить версию SSL, которую поддерживает браузер?

Я хотел бы показать сообщение клиентам, чей самый высокий уровень шифрования в браузере - SSLv3. Можно ли настроить таргетинг на настройки браузера SSLv3 и ниже? Код клиента или сервера? Мы будем разрешать более низкие версии SSL использовать наш сайт в течение определенного льготного периода. В течение этого льготного периода мы хотели бы отображать сообщение только тем пользователям, которые имеют настройки браузера SSL3 или ниже.

3 ответа

Не легко. Поддерживаемые браузером версии SSL не могут быть обнаружены до тех пор, пока не будет выполнено квитирование SSL, и даже тогда, только если браузер использует квитирование SSLv2 для обеспечения динамического согласования версий. Если будет обнаружена неподдерживаемая версия, вы не сможете отправить сообщение обратно, так как рукопожатие не удалось, и соединение будет закрыто, прежде чем вы сможете отправить любое сообщение. Однако сам SSL имеет пакет ошибок, который отправляется во время квитирования, и он может указывать на ошибку несоответствия версий.

Лучшее, что вы можете сделать в своем собственном коде, - это поддерживать все версии SSL на стороне сервера, позволить клиенту нормально завершить рукопожатие, а затем определить, какая версия фактически использовалась, и отправить обратно сообщение, если версия SSL слишком мала.

Или вы можете просто включить только TLSv1 или выше и просто отказаться от подключения старых клиентов вообще. Они просто не получили бы красивое сообщение об ошибке, если бы браузер не решил обнаружить ошибку несоответствия версии SSL и показать свое собственное красивое сообщение об этом.

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

TLSClient Hello сообщение, отправляемое, когда соединение инициируется браузером, должно содержать самую высокую версию TLS, которую он поддерживает:

   client_version
      The version of the TLS protocol by which the client wishes to
      communicate during this session.  This SHOULD be the latest
      (highest valued) version supported by the client.  For this
      version of the specification, the version will be 3.3 (see
      Appendix E for details about backward compatibility).

Приложение E, конечно, стоит посмотреть.

(The Client Hello сообщение также будет содержать список наборов шифров, которые поддерживает клиент, что, возможно, имеет отношение к общей идее вашего вопроса.)

Конечно, эта спецификация является просто "СЛЕДУЕТ", поэтому клиент, поддерживающий TLS 1.2, все еще может отправить Client Hello для TLS 1.1, но какой в ​​этом смысл? При этом у него никогда не будет возможности использовать TLS 1.2. Это может быть поле предпочтений, которое отключено, но это фактически сделает его клиентом, который в любом случае не поддерживает самую высокую версию. (Если вы хотите что-то более тонкое, вам нужно создать базу данных известных пользовательских агентов, которая будет частично ненадежной, и для которой вам нужно будет проанализировать полную строку пользовательского агента, чтобы узнать все возможное о платформе.)

Теперь, как передать содержание Client Hello сообщение в ваше приложение - это другой вопрос, и оно очень сильно зависит от того, какой стек SSL/TLS вы используете. Это может быть даже невозможно напрямую без изменения библиотеки SSL/TLS или используемого вами сервера.

При этом, как правило, вы можете получить согласованную версию TLS во время текущего сеанса довольно легко. Поскольку эта версия является "более низкой, чем предложенная клиентом в клиенте привет, и самой высокой, поддерживаемой сервером" (то есть "min(max(client), max(server))"). Если ваш сервер поддерживает SSLv3, TLS 1.0, TLS 1.1 и TLS 1.2, а последняя версия - TLS 1.2, в любом случае, то, что вы получите во время текущего соединения, также будет максимальным, который в настоящее время поддерживается клиентом. Пока так как ваш сервер поддерживает последнюю версию, вы должны знать, что клиент в лучшем случае поддерживает, из любого живого соединения.

Если вы находитесь за HTTP-сервером Apachemod_sslвы должны быть в состоянии получить это от SSL_PROTOCOL переменная окружения. Вы также должны иметь возможность получить протокол от SSLSession на Яве.

(Если вы хотите написать более специализированную службу, вы можете передать дополнительную информацию, например, наборы шифров, непосредственно в ваше приложение, как это делает служба Qualys SSL Labs, хотя я не уверен, что она должна быть широко доступной или просто тестовый сервис.)

Я должен согласиться с Реми, что это немного сложно.

Однако хорошей отправной точкой может быть получение некоторой информации о SSL (сертификате).

Что-то похожее на это:

X509Certificate certChain[] = 
(X509Certificate[]) req.getAttribute("javax.net.ssl.peer_certificates");

Еще один способ получить больше информации - получить атрибут cipher_suite (аналогично фрагменту кода выше).

javax.net.ssl.cipher_suite

Я надеюсь, что это (по крайней мере) приближает вас.

Удачи.

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