Как я могу изящно завершить сеанс Java SSL без закрытия базового сокета?Выключение SSL без закрытия основного сокета?
Сценарий заключается в том, что клиент Java подключается к (не-java) серверу, настраивает SSL и безопасно отправляет на сервер учетные данные (имя пользователя &). Сервер настраивает среду, запущенную под этими учетными данными, порождает новый процесс в этой среде и передает ему дескриптор сокета, но уловка в том, что этот новый процесс не может повторно использовать существующее SSL-соединение (и не может использовать сеанс SSL возобновление) ... поэтому идея состоит в том, чтобы выключить SSL до того, как этот новый процесс будет создан, а затем повторно согласовать сеанс SSL с нуля с новым процессом.
Проблема заключается в том, что метод Java SSLSocket's1010 закрывает сокет в дополнение к завершению сеанса SSL (по sending the close_notify alert). Кажется, что не существует эквивалента функции OpenSSL SSL_shutdown(), которая позволяет оставить открытое гнездо открытым.
Я попробовал несколько вещей, чтобы обойти это:
Использование SSLSocket.startHandshake() во второй раз, но автоматически пытается возобновить существующий кэшированные SSL сеанс (который терпит неудачу, так как этот процесс породил сервер не знать этот сеанс), и, хотя существует метод force resuming SSL sessions or die trying, нет способа аннулировать все кэшированные сеансы или отключить использование кэшированных сеансов.
Создание
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 гнездом, альтернативой является перезапись сервера клиента & для использования двух отдельных сокетов (что становится довольно беспорядочным с точки зрения необходимости противодействия отказу в обслуживании и man- в-середине атаки, и разве это не то, для чего должен использоваться SSL?).
Любой вход или мысли о путях решения этой проблемы были бы наиболее желанными.
Вы пытались использовать обычную Socket в фоновом режиме? Что-то вроде: `Socket s = новый Socket (HOST, PORT); SSLSocket ssl = ...; ssl.connect (s.getRemoteSocketAddress()); ... `? (для меня, по крайней мере, он не закрывает «базовый» сокет. * Возможно, я делаю что-то неправильно * :)) – dacwe 2010-12-06 08:23:07
dacwe, как можно ближе (игнорируя ... часть вашего фрагмента), делая ssl.connect() создаст второе соединение с хостом, и сокет `s` вообще не будет использоваться для связи SSL. – Caspar 2010-12-07 00:58:13