Как я могу корректно завершить сеанс Java SSL без закрытия основного сокета?
Сценарий заключается в том, что клиент Java подключается к серверу (не Java), устанавливает SSL и безопасно отправляет учетные данные (пользовательимя и пароль) на сервер.Сервер настраивает среду, работающую под этими учетными данными, порождает новый процесс в этой среде и передает ему дескриптор сокета, но суть в том, что этот новый процесс не может повторно использовать существующее соединение SSL (и не может использовать сеанс SSLвозобновление) ... так что идея состоит в том, чтобы отключить SSL до того, как этот новый процесс будет запущен, а затем заново согласовать сеанс SSL с нуля с новым процессом.
Проблема заключается в том, что SSLSocket в Java *Метод 1006 * close()
закрывает сокет в дополнение к закрытию сеанса SSL ( отправляет предупреждение close_notify ).Кажется, не существует эквивалента функции OpenSSL SSL_shutdown () , которая позволяет оставить базовый сокет открытым.
Я пробовал несколько вещей, чтобы обойти это:
Использование SSLSocket.startHandshake () во второй раз, но это автоматически пытается возобновить существующий кэшированный сеанс SSL (который завершается неудачей, поскольку порожденный серверный процесс не знает об этомсеанс), и, хотя существует метод для принудительного возобновления сеансов SSL или прекращения попытки , нет способа аннулировать все кэшированные сеансы или отключить использование кэшированных сеансов.
Создание SSLSocket
поверх моего существующего сокета с использованием SSLSocketFactory.createSocket () , с autoClose
, установленным в false.Это не останавливает метод close()
от закрытия базового сокета, и я подозреваю, что параметр autoClose
предотвращает закрытие сокета только при сбое первоначального рукопожатия.
Создание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 не предназначен в первую очередь?).
Любой вклад или мысли о способах решения этой проблемы будут приветствоваться.