Выключение SSL без закрытия основного сокета? - PullRequest
5 голосов
/ 06 декабря 2010

Как я могу корректно завершить сеанс Java SSL без закрытия основного сокета?

Сценарий заключается в том, что клиент Java подключается к серверу (не Java), устанавливает SSL и безопасно отправляет учетные данные (пользовательимя и пароль) на сервер.Сервер настраивает среду, работающую под этими учетными данными, порождает новый процесс в этой среде и передает ему дескриптор сокета, но суть в том, что этот новый процесс не может повторно использовать существующее соединение SSL (и не может использовать сеанс SSLвозобновление) ... так что идея состоит в том, чтобы отключить SSL до того, как этот новый процесс будет запущен, а затем заново согласовать сеанс SSL с нуля с новым процессом.

Проблема заключается в том, что SSLSocket в Java *Метод 1006 * close() закрывает сокет в дополнение к закрытию сеанса SSL ( отправляет предупреждение close_notify ).Кажется, не существует эквивалента функции OpenSSL SSL_shutdown () , которая позволяет оставить базовый сокет открытым.

Я пробовал несколько вещей, чтобы обойти это:

  1. Использование SSLSocket.startHandshake () во второй раз, но это автоматически пытается возобновить существующий кэшированный сеанс SSL (который завершается неудачей, поскольку порожденный серверный процесс не знает об этомсеанс), и, хотя существует метод для принудительного возобновления сеансов SSL или прекращения попытки , нет способа аннулировать все кэшированные сеансы или отключить использование кэшированных сеансов.

  2. Создание SSLSocket поверх моего существующего сокета с использованием SSLSocketFactory.createSocket () , с autoClose, установленным в false.Это не останавливает метод close() от закрытия базового сокета, и я подозреваю, что параметр autoClose предотвращает закрытие сокета только при сбое первоначального рукопожатия.

  3. СозданиеSSLSocket поверх существующего сокета (как указано выше), затем создание второго SSLSocket для использования для рукопожатия SSL с порожденным процессом (из нового SSLContext ).Это терпит неудачу, потому что когда сервер отправляет предупреждение close_notify (до запуска подпроцесса), Java закрывает сокет.

Я слышал о SSLEngine ,но я также прочитал (хотя источник в настоящее время ускользает от меня), что очень много трудных попыток написать правильную реализацию SSL поверх TCP / IP с его использованием, и это кажется излишним, когда все, что мне нужно, это иметь версиюSSLSocket, чей close() не вызывает super.Close().

Однако SSLSocket, похоже, даже не отменяет close() (согласно javadoc), поэтому я не уверен, как этоперехватывает метод close(), когда не представляется никакой поддержки для регистрации близких слушателей на Socket.

Политика компании требует, чтобы никакие сторонние библиотеки шифрования не могли использоваться, поэтому я не могу обратиться кальтернативная реализация SSL, например, с помощью Bouncy Castle для решения проблемы.

Если мы не можем заставить работать текущий дизайн с 1 сокетом, альтернатива - переписать клиент &сервер использует 2 отдельных сокета (что довольно сложно для противодействия отказу в обслуживании и атакам типа «человек посередине», и разве для этого SSL не предназначен в первую очередь?).

Любой вклад или мысли о способах решения этой проблемы будут приветствоваться.

Ответы [ 2 ]

2 голосов
/ 07 декабря 2010

Вы должны иметь возможность использовать простой базовый сокет (ваш # 3), так как это делают реализации FTP с Clear Control Channel.

Помните, что то, что вы пытаетесь сделать, оставляет васоткрыт для атаки «человек посередине» между двумя сеансами SSL, если только вы не несете какой-то секрет между ними, чтобы сигнализировать о том, что аутентификация по-прежнему действительна.стать прокси между клиентом и сервером.

Пересылать пакеты в обоих направлениях, пока аутентификация не завершится и сеанс SSL не закончится.(Любой SSL ALERT будет сигнализировать об окончании, нам не нужно расшифровывать содержимое). Закройте сокет для клиента, чтобы он выдавал ошибку. Выполните мои собственные переговоры SSLсервер. Перейдите к работе с учетными данными клиента.
2 голосов
/ 06 декабря 2010

Это не останавливает метод close () от закрытия основной розетки

Да, это так. Согласно документации.

и я подозреваю, что автоЗакрыть параметр только предотвращает сокет от закрытия, когда начальный рукопожатие не удается.

Нет. Это предотвращает закрытие основного сокета. Согласно документации.

Покажите нам код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...