Класс SSLEngine
public abstract class SSLEngine extends Object
Режим безопасного общения включает:
- Защита целостности. SSL/TLS/DTLS защищают от изменения сообщений активным перехватом.
- Аутентификация. В большинстве режимов SSL/TLS/DTLS обеспечивает аутентификацию участников. Серверы обычно аутентифицируются, а клиенты могут быть аутентифицированы по запросу серверов.
- Конфиденциальность (защита конфиденциальности). В большинстве режимов SSL/TLS/DTLS шифрует данные, передаваемые между клиентом и сервером. Это защищает конфиденциальность данных, так что пассивные перехватывающие устройства не увидят конфиденциальные данные, такие как финансовая информация или личная информация многих типов.
Используемый набор шифров устанавливается с помощью процесса согласования, называемого "рукопожатием". Цель этого процесса заключается в создании или возобновлении "сеанса", который может защищать многочисленные подключения со временем. После завершения рукопожатия вы можете получить доступ к атрибутам сеанса, используя метод getSession().
Класс SSLSocket предоставляет аналогичные функции безопасности, но все входящие и исходящие данные автоматически передаются с помощью базового Socket, который по своему дизайну использует блокирующий механизм. Хотя это подходит для многих приложений, эта модель не обеспечивает масштабируемость, необходимую для крупных серверов.
Основное отличие класса SSLEngine состоит в том, что он работает с входными и выходными байтовыми потоками, независимо от механизма транспорта. Пользователь SSLEngine отвечает за организацию надежной транспортной системы ввода-вывода к узлу. Разделяя абстракцию SSL/TLS/DTLS от механизма транспортной системы ввода-вывода, SSLEngine может использоваться для различных типов ввода-вывода, таких как non-blocking I/O (polling), selectable non-blocking I/O, Socket и традиционные потоки ввода/вывода, локальные ByteBuffers или массивы байтов, будущие асинхронные модели ввода-вывода и так далее.
В целом, SSLEngine выглядит следующим образом:
app data
| ^
| | |
v | |
+----+-----|-----+----+
| | |
| SSL|Engine |
wrap() | | | unwrap()
| OUTBOUND | INBOUND |
| | |
+----+-----|-----+----+
| | ^
| | |
v |
net data
Данные приложения (также известные как открытый текст) представляют собой данные, создаваемые или потребляемые приложением. Их аналогом являются сетевые данные, состоящие либо из данных рукопожатия и/или зашифрованных данных, предназначенных для передачи через механизм ввода-вывода. Входящие данные — это данные, полученные от узла, а исходящие данные предназначены для узла. (В контексте SSLEngine термин "данные рукопожатия" означает любые данные, обмениваемые для установления и управления безопасным подключением. Данные рукопожатия включают сообщения SSL/TLS/DTLS "alert", "change_cipher_spec" и "handshake").
Существует пять различных фаз работы SSLEngine.
- Создание —
SSLEngineсоздан и инициализирован, но еще не используется. На этом этапе приложение может установить любые параметры, специфичные дляSSLEngine(активные наборы шифров, режим рукопожатияSSLEngineкак клиент или сервер и т.д.). Однако после начала рукопожатия любые новые параметры (кроме режима клиент/сервер, см. ниже) будут использоваться для следующего рукопожатия. - Первоначальное рукопожатие — первоначальное рукопожатие — это процедура, в ходе которой два узла обмениваются параметрами связи до тех пор, пока не будет установлен SSLSession. Данные приложения не могут быть отправлены на этом этапе.
- Данные приложения — после установления параметров связи и завершения рукопожатия данные приложения могут передаваться через
SSLEngine. Выходные сообщения приложения шифруются и защищаются от целостности, а входные сообщения — наоборот. - Переподключение — любая сторона может запросить переподключение сеанса в любой момент во время фазы "Данные приложения". Новые данные рукопожатия могут быть перемешаны среди данных приложения. Перед началом фазы переподключения приложение может сбросить параметры связи SSL/TLS/DTLS, такие как список включенных наборов шифров и использование аутентификации клиента, но не может переключаться между режимами клиент/сервер. Как и прежде, после начала рукопожатия любые новые параметры конфигурации
SSLEngineне будут использоваться до следующего рукопожатия. - Закрытие — когда соединение больше не требуется, клиентские и серверные приложения должны закрыть обе стороны своих соответствующих соединений. Для объектов
SSLEngineприложение должно вызватьcloseOutbound()и отправить любые оставшиеся сообщения узлу. Аналогично, приложение должно получить любые оставшиеся сообщения от узла перед вызовомcloseInbound(). После закрытия обеих сторонSSLEngineможно закрыть базовый механизм транспорта. Если соединение не закрыто должным образом (например,closeInbound()вызывается до получения уведомления о закрытии записи узла), будут вызваны исключения, указывающие на возникновение ошибки. После закрытия движка он не может быть повторно использован: необходимо создать новыйSSLEngine.
SSLEngine создается путем вызова SSLContext.createSSLEngine() из инициализированного SSLContext. Все параметры конфигурации должны быть установлены перед первым вызовом wrap(), unwrap() или beginHandshake(). Эти методы вызывают первоначальное рукопожатие. Передача данных через движок осуществляется путем вызова wrap() или unwrap() для исходящих или входящих данных соответственно. В зависимости от состояния SSLEngine, вызов wrap() может потреблять данные приложения из исходного буфера и может производить сетевые данные в целевом буфере. Выходные данные могут содержать данные приложения и/или рукопожатия. Вызов unwrap() проверит исходный буфер и может перейти к рукопожатию, если данные являются информацией о рукопожатии, или поместить данные приложения в целевой буфер, если данные представляют собой данные приложения. Состояние базового алгоритма SSL/TLS/DTLS определяет, когда данные потребляются и производятся.
Вызовы wrap() и unwrap() возвращают SSLEngineResult, который указывает состояние операции и (необязательно) способ взаимодействия с движком для дальнейшего продвижения.
SSLEngine производит/потребляет только полные пакеты SSL/TLS/DTLS и не хранит данные приложения во внутренней памяти между вызовами wrap()/unwrap(). Поэтому входные и выходные ByteBuffer должны быть достаточно большими для хранения максимального пакета. Для определения соответствующих размеров буферов следует использовать вызовы SSLSession.getPacketBufferSize() и SSLSession.getApplicationBufferSize(). Размер выходного буфера данных приложения обычно не имеет значения. Если условия буфера не позволяют правильно потреблять/производить данные, приложение должно определить (через SSLEngineResult) и исправить проблему, а затем повторить вызов.
Например, unwrap() вернет результат SSLEngineResult.Status.BUFFER_OVERFLOW, если движок определит, что места в целевом буфере недостаточно. Приложения должны вызвать SSLSession.getApplicationBufferSize() и сравнить это значение с размером, доступным в целевом буфере, увеличив буфер при необходимости. Аналогично, если unwrap() вернет SSLEngineResult.Status.BUFFER_UNDERFLOW, приложение должно вызвать SSLSession.getPacketBufferSize(), чтобы убедиться, что исходный буфер достаточно велик для хранения пакета (увеличив его при необходимости), и затем получить больше входящих данных.
SSLEngineResult r = engine.unwrap(src, dst);
switch (r.getStatus()) {
case BUFFER_OVERFLOW:
// Could attempt to drain the dst buffer of any already obtained
// data, but we'll just increase it to the size needed.
int appSize = engine.getSession().getApplicationBufferSize();
ByteBuffer b = ByteBuffer.allocate(appSize + dst.position());
dst.flip();
b.put(dst);
dst = b;
// retry the operation.
break;
case BUFFER_UNDERFLOW:
int netSize = engine.getSession().getPacketBufferSize();
// Resize buffer if needed.
if (netSize > src.capacity()) {
ByteBuffer b = ByteBuffer.allocate(netSize);
src.flip();
b.put(src);
src = b;
}
// Obtain more inbound network data for src,
// then retry the operation.
break;
// other cases: CLOSED, OK.
}
В отличие от SSLSocket, все методы SSLEngine неблокирующие. Реализации SSLEngine могут потребовать результатов задач, выполнение которых может занять значительное время, или даже заблокироваться. Например, менеджер доверия может потребовать подключения к удаленной службе проверки сертификатов, или менеджер ключей может потребовать запросить у пользователя, какой сертификат использовать в рамках аутентификации клиента. Кроме того, создание и проверка криптографических подписей могут быть медленными, создавая видимость блокировки.
Для любых операций, которые могут потенциально заблокировать выполнение, SSLEngine создаст делегированную задачу Runnable. Когда SSLEngineResult указывает, что требуется результат делегированной задачи, приложение должно вызвать getDelegatedTask() для получения ожидающей делегированной задачи и вызвать ее метод run() (возможно, используя другой поток в зависимости от стратегии вычислений). Приложение должно продолжать получать делегированные задачи до тех пор, пока они не закончатся, и повторить исходную операцию.
В конце сеанса связи приложения должны правильно закрыть соединение SSL/TLS/DTLS. Протоколы SSL/TLS/DTLS имеют сообщения рукопожатия закрытия, и эти сообщения должны быть переданы узлу перед высвобождением SSLEngine и закрытием базового механизма транспорта. Закрытие может быть инициировано одним из следующих способов: SSLException, сообщение о закрытии входящего рукопожатия или одним из методов закрытия. Во всех случаях сообщения рукопожатия закрытия генерируются движком, и wrap() следует вызывать повторно до тех пор, пока состояние возвращаемого SSLEngineResult не станет "CLOSED", или пока isOutboundDone() не вернет true. Все данные, полученные от метода wrap(), должны быть отправлены узлу.
closeOutbound() используется для сигнализации движку о том, что приложение не будет отправлять больше данных.
Узел будет сигнализировать о своем намерении закрыть соединение, отправив собственное сообщение закрытия. После получения и обработки этого сообщения локальным SSLEngine's unwrap() вызовом, приложение может обнаружить закрытие, вызвав unwrap() и найдя SSLEngineResult со статусом "ЗАКРЫТО", или если isInboundDone() возвращает true. Если по какой-то причине узел закрывает канал связи без отправки соответствующего сообщения закрытия SSL/TLS/DTLS, приложение может обнаружить конец потока и сообщить об этом движку с помощью closeInbound(), что больше нет входящих сообщений для обработки. Некоторые приложения могут потребовать упорядоченных сообщений о закрытии от узла, в этом случае они могут проверить, что закрытие было вызвано сообщением рукопожатия, а не состоянием конца потока.
Существует две группы наборов шифрования, о которых вам нужно знать при управлении наборами шифрования:
- Поддерживаемые наборы шифрования: все наборы, которые поддерживаются реализацией SSL. Этот список предоставляется с помощью
getSupportedCipherSuites(). - Включенные наборы шифрования, количество которых может быть меньше полного набора поддерживаемых наборов. Эта группа настраивается с помощью метода
setEnabledCipherSuites(String[])и запрашивается с помощью методаgetEnabledCipherSuites(). Изначально на новом движке будет включен набор по умолчанию, представляющий минимальную рекомендуемую конфигурацию.
Каждое SSL/TLS/DTLS соединение должно иметь один клиент и один сервер, следовательно, каждый конечный пункт должен выбрать, какую роль принять. Этот выбор определяет, кто начинает процесс рукопожатия, а также какие типы сообщений должны отправляться каждой стороной. Метод setUseClientMode(boolean) настраивает режим. Обратите внимание, что режим по умолчанию для нового SSLEngine зависит от поставщика. Приложения должны явно установить режим перед вызовом других методов SSLEngine. После начала начального рукопожатия SSLEngine не может переключаться между режимами клиента и сервера, даже при выполнении повторных переговоров.
Значения ApplicationProtocol String, возвращаемые методами в этом классе, представлены в сетевом байтовом представлении, отправляемом узлом. Байты можно напрямую сравнивать или преобразовывать в формат Unicode String для сравнения.
String networkString = sslEngine.getHandshakeApplicationProtocol();
byte[] bytes = networkString.getBytes(StandardCharsets.ISO_8859_1);
//
// Match using bytes:
//
// "http/1.1" (7-bit ASCII values same in UTF-8)
// MEETEI MAYEK LETTERS "HUK UN I" (Unicode 0xabcd->0xabcf)
//
String HTTP1_1 = "http/1.1";
byte[] HTTP1_1_BYTES = HTTP1_1.getBytes(StandardCharsets.UTF_8);
byte[] HUK_UN_I_BYTES = new byte[] {
(byte) 0xab, (byte) 0xcd,
(byte) 0xab, (byte) 0xce,
(byte) 0xab, (byte) 0xcf};
if ((Arrays.compare(bytes, HTTP1_1_BYTES) == 0 )
|| Arrays.compare(bytes, HUK_UN_I_BYTES) == 0) {
...
}
//
// Alternatively match using string.equals() if we know the ALPN value
// was encoded from a String using a certain character set,
// for example UTF-8. The ALPN value must first be properly
// decoded to a Unicode String before use.
//
String unicodeString = new String(bytes, StandardCharsets.UTF_8);
if (unicodeString.equals(HTTP1_1)
|| unicodeString.equals("\uabcd\uabce\uabcf")) {
...
}
Примечания по конкурентности: Следует учитывать две проблемы конкурентности: - Методы
wrap()иunwrap()могут выполняться одновременно друг с другом. - Протоколы SSL/TLS/DTLS используют упорядоченные пакеты. Приложения должны позаботиться о том, чтобы сгенерированные пакеты передавались последовательно. Если пакеты приходят в неупорядоченном порядке, могут возникнуть непредвиденные или фатальные результаты.
Например:
synchronized (outboundLock) { sslEngine.wrap(src, dst); outboundQueue.put(dst); }Соответственно, два потока не должны пытаться вызвать один и тот же метод (либоwrap(), либоunwrap()) одновременно, потому что нет способа гарантировать конечную упорядоченность пакетов.
- Since:
- 1.5
- Внешние спецификации
- См. также:
Краткое описание конструкторов
| Модификатор | Конструктор | Описание |
|---|---|---|
protected |
Конструктор для SSLEngine, не предоставляющего подсказок для стратегии повторного использования внутренней сессии. |
|
protected |
Конструктор для SSLEngine. |
Краткое описание методов
| Модификатор и тип | Метод | Описание |
|---|---|---|
abstract void |
beginHandshake() |
Инициирует установление рукопожатия (начальное или повторное) для этого SSLEngine. |
abstract void |
closeInbound() |
Сигнализирует о том, что больше не будет отправляться входящие сетевые данные в этот SSLEngine. |
abstract void |
closeOutbound() |
Сигнализирует о том, что больше не будет отправляться исходящие данные приложения в этом SSLEngine. |
String |
getApplicationProtocol() |
Возвращает последнее значение протокола приложения, согласованное для этого подключения. |
abstract Runnable |
getDelegatedTask() |
Возвращает делегированную задачу Runnable для этого SSLEngine. |
abstract String[] |
getEnabledCipherSuites() |
Возвращает имена наборов шифрования SSL, которые в настоящее время включены для использования в этом модуле. |
abstract String[] |
getEnabledProtocols() |
Возвращает имена версий протоколов, которые в настоящее время включены для использования с этим SSLEngine. |
abstract boolean |
getEnableSessionCreation() |
Возвращает true, если этот модуль может устанавливать новые сессии SSL. |
String |
getHandshakeApplicationProtocol() |
Возвращает значение протокола приложения, согласованное во время текущего процесса рукопожатия SSL/TLS. |
BiFunction |
getHandshakeApplicationProtocolSelector() |
Извлекает функцию обратного вызова, которая выбирает значение протокола приложения во время процесса рукопожатия SSL/TLS/DTLS. |
SSLSession |
getHandshakeSession() |
Возвращает SSLSession, формируемый во время процесса рукопожатия SSL/TLS/DTLS. |
abstract SSLEngineResult.HandshakeStatus |
getHandshakeStatus() |
Возвращает текущий статус рукопожатия для этого SSLEngine. |
abstract boolean |
getNeedClientAuth() |
Возвращает true, если модуль будет требовать аутентификацию клиента. |
String |
getPeerHost() |
Возвращает имя хоста удалённого узла. |
int |
getPeerPort() |
Возвращает номер порта удалённого узла. |
abstract SSLSession |
getSession() |
Возвращает используемые SSLSession в этом SSLEngine. |
SSLParameters |
getSSLParameters() |
Возвращает SSLParameters, действующие для этого SSLEngine. |
abstract String[] |
getSupportedCipherSuites() |
Возвращает имена наборов шифрования, которые могут быть включены для использования в этом модуле. |
abstract String[] |
getSupportedProtocols() |
Возвращает имена протоколов, которые могут быть включены для использования с этим SSLEngine. |
abstract boolean |
getUseClientMode() |
Возвращает true, если модуль настроен на использование клиентского режима при установлении рукопожатия. |
abstract boolean |
getWantClientAuth() |
Возвращает true, если модуль будет запрашивать аутентификацию клиента. |
abstract boolean |
isInboundDone() |
Возвращает, будет ли unwrap(ByteBuffer, ByteBuffer) принимать дополнительные сообщения входящих данных. |
abstract boolean |
isOutboundDone() |
Возвращает, будет ли wrap(ByteBuffer, ByteBuffer) генерировать дополнительные сообщения исходящих данных. |
abstract void |
setEnabledCipherSuites |
Устанавливает наборы шифрования, включенные для использования в этом модуле. |
abstract void |
setEnabledProtocols |
Устанавливает версии протоколов, включенные для использования в этом модуле. |
abstract void |
setEnableSessionCreation |
Управляет возможностью установки новых сессий SSL этим модулем. |
void |
setHandshakeApplicationProtocolSelector |
Регистрирует функцию обратного вызова, которая выбирает значение протокола приложения для процесса рукопожатия SSL/TLS/DTLS. |
abstract void |
setNeedClientAuth |
Настраивает модуль для требования аутентификации клиента. |
void |
setSSLParameters |
Применяет SSLParameters к этому модулю. |
abstract void |
setUseClientMode |
Настраивает модуль для использования клиентского (или серверного) режима при установлении рукопожатия. |
abstract void |
setWantClientAuth |
Настраивает модуль для запроса аутентификации клиента. |
SSLEngineResult |
unwrap |
Попытка декодировать сетевые данные SSL/TLS/DTLS в буфер данных приложения в формате простого текста. |
SSLEngineResult |
unwrap |
Попытка декодировать сетевые данные SSL/TLS/DTLS в последовательность буферов данных приложения в формате простого текста. |
abstract SSLEngineResult |
unwrap |
Попытка декодировать сетевые данные SSL/TLS/DTLS в подпоследовательность буферов данных приложения в формате простого текста. |
abstract SSLEngineResult |
wrap |
Попытка закодировать байты простого текста из подпоследовательности буферов данных в сетевые данные SSL/TLS/DTLS. |
SSLEngineResult |
wrap |
Попытка закодировать байты простого текста из последовательности буферов данных в сетевые данные SSL/TLS/DTLS. |
SSLEngineResult |
wrap |
Попытка закодировать буфер данных приложения в формате простого текста в сетевые данные SSL/TLS/DTLS. |
Подробное описание конструкторов
SSLEngine
protected SSLEngine()
SSLEngine, не предоставляющий подсказок для стратегии повторного использования внутренней сессии.- См. также:
SSLEngine
protected SSLEngine(String peerHost, int peerPort)
SSLEngine. Реализации SSLEngine могут использовать параметры peerHost и peerPort в качестве подсказок для своей внутренней стратегии повторного использования сессии.
Некоторые наборы шифров (такие как Kerberos) требуют информацию о удалённом имени хоста. Реализации этого класса должны использовать этот конструктор для использования Kerberos.
Параметры не аутентифицируются SSLEngine.
- Параметры:
-
peerHost- имя хоста удалённого узла -
peerPort- номер порта удалённого узла - См. также:
Подробное описание методов
getPeerHost
public String getPeerHost()
Обратите внимание, что значение не аутентифицировано и не должно использоваться.
- Возвращает:
- имя хоста удалённого узла, или null, если ничего не доступно.
getPeerPort
public int getPeerPort()
Обратите внимание, что значение не аутентифицировано и не должно использоваться.
- Возвращает:
- номер порта удалённого узла, или -1, если ничего не доступно.
wrap
public SSLEngineResult wrap(ByteBuffer src, ByteBuffer dst) throws SSLException
Вызов этого метода работает точно так же, как вызов:
engine.wrap(new ByteBuffer[] { src }, 0, 1, dst);
- Параметры:
-
src- aByteBufferсодержащий исходящие данные приложения -
dst- aByteBufferдля хранения исходящих сетевых данных - Возвращает:
SSLEngineResultописывающий результат этой операции.- Исключения:
-
SSLException- Произошла проблема при обработке данных, которая привела к прерываниюSSLEngine. См. описание класса для получения дополнительной информации о закрытии движка. -
ReadOnlyBufferException- если буферdstтолько для чтения. -
IllegalArgumentException- если либоsrc, либоdstравно null. -
IllegalStateException- если режим клиент/сервер ещё не задан. - См. также:
wrap
public SSLEngineResult wrap(ByteBuffer[] srcs, ByteBuffer dst) throws SSLException
Вызов этого метода работает точно так же, как вызов:
engine.wrap(srcs, 0, srcs.length, dst);
- Параметры:
-
srcs- массивByteBuffers, содержащий исходящие данные приложения -
dst- aByteBufferдля хранения исходящих сетевых данных - Возвращает:
SSLEngineResult, описывающий результат этой операции.- Исключения:
-
SSLException- Произошла проблема при обработке данных, которая привела к прерываниюSSLEngine. См. описание класса для получения дополнительной информации о закрытии движка. -
ReadOnlyBufferException- если буферdstтолько для чтения. -
IllegalArgumentException- если либоsrcs, либоdstравно null, или если какой-либо элемент вsrcsравен null. -
IllegalStateException- если режим клиент/сервер ещё не задан. - См. также:
wrap
public abstract SSLEngineResult wrap(ByteBuffer[] srcs, int offset, int length, ByteBuffer dst) throws SSLException
GatheringByteChannel для получения дополнительной информации о сборе и GatheringByteChannel.write(ByteBuffer[], int, int) для получения дополнительной информации о поведении подпоследовательности. В зависимости от состояния SSLEngine, этот метод может генерировать сетевые данные без потребления данных приложения (например, он может генерировать данные рукопожатия).
Приложение отвечает за надёжную передачу сетевых данных к удалённому узлу и за обеспечение того, чтобы данные, созданные множественными вызовами wrap(), передавались в том же порядке, в котором они были созданы. Приложение должно правильно синхронизировать несколько вызовов этого метода.
Если этот SSLEngine ещё не начал начальное рукопожатие, этот метод автоматически начнёт рукопожатие.
Этот метод попытается создать записи SSL/TLS/DTLS и израсходует как можно больше исходных данных, но никогда не израсходует больше, чем сумма оставшихся байтов в каждом буфере. Позиция каждого ByteBuffer обновляется для отражения объёма потребленных или произведённых данных. Пределы остаются неизменными.
Подлежащая память, используемая srcs и dst ByteBuffer, не должна быть одинаковой.
См. описание класса для получения дополнительной информации о закрытии движка.
- Параметры:
-
srcs- массивByteBuffers, содержащий исходящие данные приложения -
offset- Смещение в массиве буферов первого буфера, из которого будут извлекаться байты; оно должно быть неотрицательным и не большеsrcs.length -
length- Максимальное количество буферов для доступа; оно должно быть неотрицательным и не большеsrcs.length-offset -
dst- aByteBufferдля хранения исходящих сетевых данных - Возвращает:
SSLEngineResult, описывающий результат этой операции.- Исключения:
-
SSLException- Произошла проблема при обработке данных, которая привела к прерываниюSSLEngine. См. описание класса для получения дополнительной информации о закрытии движка. -
IndexOutOfBoundsException- если условия дляoffsetиlengthпараметров не соблюдаются. -
ReadOnlyBufferException- если буферdstтолько для чтения. -
IllegalArgumentException- если либоsrcs, либоdstравно null, или если какой-либо элемент в подпоследовательностиsrcsуказанной равен null. -
IllegalStateException- если режим клиент/сервер ещё не задан. - См. также:
unwrap
public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer dst) throws SSLException
Вызов этого метода работает точно так же, как вызов:
engine.unwrap(src, new ByteBuffer[] { dst }, 0, 1);
- Параметры:
-
src- aByteBuffer, содержащий входящие сетевые данные. -
dst- aByteBufferдля хранения входящих данных приложения. - Возвращает:
SSLEngineResult, описывающий результат этой операции.- Исключения:
-
SSLException- Произошла проблема при обработке данных, которая привела к прерываниюSSLEngine. См. описание класса для получения дополнительной информации о закрытии движка. -
ReadOnlyBufferException- если буферdstтолько для чтения. -
IllegalArgumentException- если либоsrc, либоdstравно null. -
IllegalStateException- если режим клиент/сервер ещё не задан. - См. также:
unwrap
public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts) throws SSLException
Вызов этого метода ведет себя точно так же, как вызов:
engine.unwrap(src, dsts, 0, dsts.length);
- Параметры:
-
src- aByteBuffer, содержащий входящие сетевые данные. -
dsts- массивByteBufferдля хранения входящих данных приложения. - Возвращает:
- a
SSLEngineResult, описывающий результат этой операции. - Исключения:
-
SSLException- При обработке данных возникла проблема, которая привела к прерыванию работыSSLEngine. Дополнительную информацию о закрытии движка см. в описании класса. -
ReadOnlyBufferException- если какой-либо из буферовdstявляется только для чтения. -
IllegalArgumentException- если либоsrc, либоdstsравно null, или если какой-либо элемент вdstsравен null. -
IllegalStateException- если режим клиент/сервер еще не установлен. - См. также:
unwrap
public abstract SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts, int offset, int length) throws SSLException
ScatteringByteChannel, а информацию о поведении подпоследовательности см. в ScatteringByteChannel.read(ByteBuffer[], int, int). В зависимости от состояния SSLEngine, этот метод может потреблять сетевые данные без создания каких-либо данных приложения (например, он может потреблять данные рукопожатия).
Приложение отвечает за надежное получение сетевых данных от peer и за вызов unwrap() для данных в порядке их получения. Приложение должно правильно синхронизировать несколько вызовов этого метода.
Если этот SSLEngine еще не начал начальное рукопожатие, этот метод автоматически начнет рукопожатие.
Этот метод попытается потреблять один полный сетевой пакет SSL/TLS/DTLS, но никогда не потребляет больше, чем сумму оставшихся байтов в буферах. Позиция каждого ByteBuffer обновляется для отражения количества потребленных или созданных данных. Пределы остаются неизменными.
Базовая память, используемая буферами src и dsts ByteBuffer, не должна совпадать.
Входящий сетевой буфер, src, может быть изменен в результате этого вызова: поэтому, если сетевой пакет данных требуется для какой-либо дополнительной цели, данные следует дублировать перед вызовом этого метода. Примечание: сетевые данные не будут полезны второму SSLEngine, так как каждый SSLEngine содержит уникальное случайное состояние, которое влияет на сообщения SSL/TLS/DTLS.
Дополнительную информацию о закрытии движка см. в описании класса.
- Параметры:
-
src- aByteBuffer, содержащий входящие сетевые данные. -
dsts- массив буферовByteBufferдля хранения входящих данных приложения. -
offset- Смещение в массиве буферов первого буфера, из которого должны быть переданы байты; оно должно быть неотрицательным и не больше, чемdsts.length. -
length- Максимальное количество буферов для доступа; оно должно быть неотрицательным и не больше, чемdsts.length-offset. - Возвращает:
- a
SSLEngineResult, описывающий результат этой операции. - Исключения:
-
SSLException- При обработке данных возникла проблема, которая привела к прерыванию работыSSLEngine. Дополнительную информацию о закрытии движка см. в описании класса. -
IndexOutOfBoundsException- Если условия предшествующих операций для параметровoffsetиlengthне выполняются. -
ReadOnlyBufferException- если какой-либо из буферовdstявляется только для чтения. -
IllegalArgumentException- если либоsrc, либоdstsравно null, или если какой-либо элемент в подпоследовательностиdstsравен null. -
IllegalStateException- если режим клиент/сервер еще не установлен. - См. также:
getDelegatedTask
public abstract Runnable getDelegatedTask()
Runnable для этого SSLEngine. Операции SSLEngine могут потребовать результатов операций, которые блокируют или могут потребовать значительного времени для завершения. Этот метод используется для получения ожидающей операции Runnable (задачи). Каждая задача должна быть назначена потоку (возможно, текущему) для выполнения операции run. После возвращения метода run объект Runnable больше не нужен и может быть удален.
Вызов этого метода вернет каждую ожидающую задачу ровно один раз.
Несколько делегированных задач могут выполняться параллельно.
- Возвращает:
- делегированная задача
Runnable, или null, если такие задачи отсутствуют.
closeInbound
public abstract void closeInbound() throws SSLException
SSLEngine. Если приложение инициировало процесс закрытия, вызвав closeOutbound(), в некоторых случаях иницииатор не обязан ожидать соответствующего сообщения о закрытии от peer. (См. раздел 7.2.1 спецификации TLS (RFC 2246) для получения дополнительной информации об ожидании сигналов закрытия.) В таких случаях вызов этого метода не требуется.
Но если приложение не инициировало процесс закрытия или если вышеперечисленные условия не применяются, этот метод следует вызвать всякий раз, когда достигается конец потока данных SSL/TLS/DTLS. Это гарантирует закрытие входящей стороны и проверяет, что peer должным образом выполнил процедуру закрытия SSL/TLS/DTLS, тем самым обнаруживая возможные атаки с обрезанием данных.
Этот метод идемпотентен: если входящая сторона уже закрыта, этот метод ничего не делает.
Для сброса любых оставшихся данных рукопожатия следует вызвать wrap().
- Исключения:
-
SSLException- если этот движок не получил надлежащее сообщение о закрытии SSL/TLS/DTLS от peer. - Внешние спецификации
- См. также:
isInboundDone
public abstract boolean isInboundDone()
unwrap(ByteBuffer, ByteBuffer) принимать дополнительные входящие сообщения.- Возвращает:
- true, если
SSLEngineне будет потреблять больше сетевых данных (и, следовательно, не будет создавать больше данных приложения.) - См. также:
closeOutbound
public abstract void closeOutbound()
SSLEngine. Этот метод идемпотентен: если исходящая сторона уже закрыта, этот метод ничего не делает.
Для сброса любых оставшихся данных рукопожатия следует вызвать wrap(ByteBuffer, ByteBuffer).
- См. также:
isOutboundDone
public abstract boolean isOutboundDone()
wrap(ByteBuffer, ByteBuffer) создавать какие-либо дополнительные исходящие сообщения. Обратите внимание, что на стадии закрытия SSLEngine может генерировать данные рукопожатия закрытия, которые должны быть отправлены peer. wrap() необходимо вызвать для генерации этих данных. Когда этот метод возвращает true, больше исходящих данных не будет создано.
- Возвращает:
- true, если
SSLEngineне будет создавать больше сетевых данных - См. также:
getSupportedCipherSuites
public abstract String[] getSupportedCipherSuites()
Возвращаемый массив включает наборы шифрования из списка стандартных имён наборов шифрования в разделе JSSE Cipher Suite Names спецификации стандартных имён алгоритмов Java Security, а также может включать и другие наборы шифрования, поддерживаемые поставщиком.
- Возвращает:
- массив имён наборов шифрования
- См. также:
getEnabledCipherSuites
public abstract String[] getEnabledCipherSuites()
Обратите внимание, что даже если набор включен, он может никогда не использоваться. Это может произойти, если удаленный узел его не поддерживает, или его использование ограничено, или необходимые сертификаты (и закрытые ключи) для набора отсутствуют, или анонимный набор включен, но требуется аутентификация.
Возвращаемый массив включает наборы шифрования из списка стандартных имён наборов шифрования в разделе JSSE Cipher Suite Names спецификации стандартных имён алгоритмов Java Security, а также может включать и другие наборы шифрования, поддерживаемые поставщиком.
- Возвращает:
- массив имён наборов шифрования
- См. также:
setEnabledCipherSuites
public abstract void setEnabledCipherSuites(String[] suites)
Каждый набор шифрования в параметре suites должен быть указан методом getSupportedCipherSuites(), иначе метод завершится ошибкой. После успешного вызова этого метода, только наборы, перечисленные в параметре suites, будут включены для использования.
Обратите внимание, что стандартный список имён наборов шифрования можно найти в разделе JSSE Cipher Suite Names спецификации стандартных имён алгоритмов Java Security. Поставщики могут поддерживать имена наборов шифрования, не найденные в этом списке, или могут не использовать рекомендуемое имя для определённого набора шифрования.
См. getEnabledCipherSuites() для получения дополнительной информации о том, почему определенный набор шифрования может никогда не использоваться в движке.
- Параметры:
-
suites- Имена всех наборов шифрования, которые нужно включить - Исключения:
-
IllegalArgumentException- если один или несколько шифров, указанных в параметре, не поддерживаются, или если параметр null. - См. также:
getSupportedProtocols
public abstract String[] getSupportedProtocols()
SSLEngine.- Возвращает:
- массив поддерживаемых протоколов
getEnabledProtocols
public abstract String[] getEnabledProtocols()
SSLEngine. Обратите внимание, что даже если протокол включен, он может никогда не использоваться. Это может произойти, если удаленный узел не поддерживает протокол, или его использование ограничено, или нет включённых наборов шифрования, поддерживаемых протоколом.
- Возвращает:
- массив протоколов
- См. также:
setEnabledProtocols
public abstract void setEnabledProtocols(String[] protocols)
Протоколы должны быть перечислены в getSupportedProtocols() как поддерживаемые. После успешного вызова этого метода, только протоколы, перечисленные в параметре protocols, будут включены для использования.
- Параметры:
-
protocols- Имена всех протоколов, которые нужно включить. - Исключения:
-
IllegalArgumentException- если один или несколько протоколов, указанных в параметре, не поддерживаются, или если параметр protocols равен null. - См. также:
getSession
public abstract SSLSession getSession()
SSLEngine. Они могут быть долгоживущими и часто соответствуют всей сессии входа пользователя. Сеанс определяет конкретный набор шифрования, который активно используется всеми подключениями в этой сессии, а также идентификаторы клиента и сервера сеанса.
В отличие от SSLSocket.getSession(), этот метод не блокируется, пока рукопожатие не завершено.
До тех пор, пока начальное рукопожатие не завершится, этот метод возвращает объект сеанса, который сообщает о недопустимом наборе шифрования "SSL_NULL_WITH_NULL_NULL".
- Возвращает:
- сеанс для этого
SSLEngine - См. также:
getHandshakeSession
public SSLSession getHandshakeSession()
Протоколы TLS/DTLS могут согласовывать параметры, которые необходимы при использовании экземпляра этого класса, но до того, как SSLSession был полностью инициализирован и доступен через getSession. Например, список допустимых алгоритмов подписи может ограничить тип сертификатов, которые могут использоваться при принятии решений TrustManager, или максимальные размеры пакетов фрагментов TLS/DTLS могут быть изменены для лучшей поддержки сетевой среды.
Этот метод предоставляет ранний доступ к создаваемому SSLSession. В зависимости от того, насколько далеко продвинулось рукопожатие, некоторые данные могут пока быть недоступны для использования. Например, если удаленный сервер будет отправлять цепочку сертификатов, но эта цепочка ещё не обработана, метод getPeerCertificates класса SSLSession бросит исключение SSLPeerUnverifiedException. После обработки этой цепочки, getPeerCertificates вернёт соответствующее значение.
- Возвращает:
- null, если этот экземпляр не участвует в рукопожатии или текущее рукопожатие не достаточно продвинуто для создания базового SSLSession. В противном случае этот метод возвращает
SSLSession, который в данный момент договаривается. - Исключения:
-
UnsupportedOperationException- если базовый поставщик не реализует операцию. - С тех пор:
- 1.7
- См. также:
beginHandshake
public abstract void beginHandshake() throws SSLException
Этот метод не нужен для начального рукопожатия, поскольку методы wrap() и unwrap() неявно вызовут этот метод, если рукопожатие ещё не началось.
Обратите внимание, что удалённый узел также может запросить повторное рукопожатие с этим SSLEngine, отправив соответствующее сообщение о повторном рукопожатии.
В отличие от метода SSLSocket#startHandshake(), этот метод не блокируется, пока рукопожатие не завершится.
Чтобы принудительно выполнить полное повторное рукопожатие сессии SSL/TLS/DTLS, текущий сеанс должен быть недействительным перед вызовом этого метода.
Некоторые протоколы могут не поддерживать несколько рукопожатий в одном движке и могут бросить исключение SSLException.
- Исключения:
-
SSLException- если возникла проблема при сигнализацииSSLEngineо начале нового рукопожатия. См. описание класса для получения дополнительной информации о закрытии движка. -
IllegalStateException- если режим клиент/сервер ещё не установлен. - См. также:
getHandshakeStatus
public abstract SSLEngineResult.HandshakeStatus getHandshakeStatus()
SSLEngine.- Возвращает:
- текущий
SSLEngineResult.HandshakeStatus.
setUseClientMode
public abstract void setUseClientMode(boolean mode)
Этот метод должен быть вызван до начала любого установления соединения. После начала установления соединения режим нельзя сбросить в течение всего жизненного цикла этого движка.
Серверы обычно аутентифицируют себя, а клиенты не обязаны этого делать.
- Примечание реализации:
- Значение по умолчанию для этого режима в реализации поставщика JDK SunJSSE равно false.
- Параметры:
-
mode- true, если движок должен начать установление соединения в "клиентском" режиме - Исключения:
-
IllegalArgumentException- если попытка изменения режима производится после начала первоначального установления соединения. - См. также:
getUseClientMode
public abstract boolean getUseClientMode()
- Примечание реализации:
- Реализация поставщика JDK SunJSSE возвращает false, если метод
setUseClientMode(boolean)не был использован для изменения режима на true. - Возвращаемое значение:
- true, если движок должен выполнять установление соединения в "клиентском" режиме
- См. также:
setNeedClientAuth
public abstract void setNeedClientAuth(boolean need)
Настройка аутентификации клиента для движка может быть одной из следующих:
- Требуется аутентификация клиента
- Запрашивается аутентификация клиента
- Аутентификация клиента не требуется
В отличие от setWantClientAuth(boolean), если этот параметр установлен, а клиент выбирает не предоставлять информацию об аутентификации, переговоры прекратятся, и движок начнёт процедуру закрытия.
Вызов этого метода перезаписывает предыдущие настройки, сделанные этим методом или setWantClientAuth(boolean).
- Параметры:
-
need- значение true, если требуется аутентификация клиента, или false, если аутентификация клиента не требуется. - См. также:
getNeedClientAuth
public abstract boolean getNeedClientAuth()
- Возвращаемое значение:
- true, если требуется аутентификация клиента, или false, если аутентификация клиента не требуется.
- См. также:
setWantClientAuth
public abstract void setWantClientAuth(boolean want)
Настройка аутентификации клиента для движка может быть одной из следующих:
- Требуется аутентификация клиента
- Запрашивается аутентификация клиента
- Аутентификация клиента не требуется
В отличие от setNeedClientAuth(boolean), если этот параметр установлен, а клиент выбирает не предоставлять информацию об аутентификации, переговоры продолжатся.
Вызов этого метода перезаписывает предыдущие настройки, сделанные этим методом или setNeedClientAuth(boolean).
- Параметры:
-
want- значение true, если запрашивается аутентификация клиента, или false, если аутентификация клиента не требуется. - См. также:
getWantClientAuth
public abstract boolean getWantClientAuth()
- Возвращаемое значение:
- true, если запрашивается аутентификация клиента, или false, если аутентификация клиента не требуется.
- См. также:
setEnableSessionCreation
public abstract void setEnableSessionCreation(boolean flag)
- Параметры:
-
flag- true указывает, что сессии могут быть созданы; это значение по умолчанию. false указывает, что должна быть возобновлена существующая сессия - См. также:
getEnableSessionCreation
public abstract boolean getEnableSessionCreation()
- Возвращаемое значение:
- true указывает, что сессии могут быть созданы; это значение по умолчанию. false указывает, что должна быть возобновлена существующая сессия
- См. также:
getSSLParameters
public SSLParameters getSSLParameters()
- Возвращаемое значение:
- SSLParameters, действующие для этого SSLEngine.
- С:
- 1.6
setSSLParameters
public void setSSLParameters(SSLParameters params)
Это означает:
- Если
params.getCipherSuites()не null,setEnabledCipherSuites()вызывается с этим значением. - Если
params.getProtocols()не null,setEnabledProtocols()вызывается с этим значением. - Если
params.getNeedClientAuth()илиparams.getWantClientAuth()возвращаютtrue,setNeedClientAuth(true)иsetWantClientAuth(true)вызываются соответственно; в противном случае вызываетсяsetWantClientAuth(false). - Если
params.getServerNames()не null, движок настроит свои имена сервера с этим значением. - Если
params.getSNIMatchers()не null, движок настроит свои SNI обработчики с этим значением.
- Параметры:
-
params- параметры - Исключения:
-
IllegalArgumentException- если вызов setEnabledCipherSuites() или setEnabledProtocols() завершается неудачно - С:
- 1.6
getApplicationProtocol
public String getApplicationProtocol()
Если поддерживается реализацией SSL/TLS/DTLS, механизмы согласования имен приложения, такие как RFC 7301, протокол согласования приложений (ALPN), могут согласовывать значения уровня приложения между узлами.
- Требования реализации:
- Реализация в этом классе выбрасывает
UnsupportedOperationExceptionи не выполняет никаких других действий. - Возвращаемое значение:
- null, если ещё не определено, могут ли быть использованы протоколы приложения для этого соединения; пустая строка
String, если протоколы приложения не будут использоваться; или непустой протокол приложенияString, если значение было успешно согласовано. - Исключения:
-
UnsupportedOperationException- если базовый поставщик не реализует операцию. - С:
- 9
- Внешние спецификации
getHandshakeApplicationProtocol
public String getHandshakeApplicationProtocol()
Как и getHandshakeSession(), соединение может быть в процессе установления соединения. Протокол приложения может или ещё не быть доступен.
- Требования реализации:
- Реализация в этом классе выбрасывает
UnsupportedOperationExceptionи не выполняет никаких других действий. - Возвращаемое значение:
- null, если ещё не определено, могут ли быть использованы протоколы приложения для этого установления соединения; пустая строка
String, если протоколы приложения не будут использоваться; или непустой протокол приложенияString, если значение было успешно согласовано. - Исключения:
-
UnsupportedOperationException- если базовый поставщик не реализует операцию. - С:
- 9
setHandshakeApplicationProtocolSelector
public void setHandshakeApplicationProtocolSelector(BiFunction<SSLEngine, List<String>, String> selector)
SSLParameters.setApplicationProtocols, и поддерживает следующие типы параметров: Например, следующий вызов регистрирует функцию обратного вызова, которая анализирует параметры рукопожатия TLS и выбирает имя протокола приложения:
SSLEngine- Первый аргумент функции позволяет просмотреть текущие
SSLEngine, включая сеанс рукопожатия и параметры конфигурации.List<String>- Второй аргумент функции содержит список имён протоколов приложения, объявленных peer TLS.
String- Результатом функции является имя протокола приложения или null, чтобы указать, что ни одно из объявленных имён неприемлемо. Если возвращаемое значение — пустая
String, то указания протокола приложения не будут использоваться. Если возвращаемое значение null (значения не выбрано) или это значение не было объявлено peer, то базовый протокол определит, какие действия предпринять. (Например, ALPN отправит предупреждение «no_application_protocol» и прервёт соединение.)
serverEngine.setHandshakeApplicationProtocolSelector(
(serverEngine, clientProtocols) -> {
SSLSession session = serverEngine.getHandshakeSession();
return chooseApplicationProtocol(
serverEngine,
clientProtocols,
session.getProtocol(),
session.getCipherSuite());
});
- Примечание API:
- Этот метод должен вызываться приложениями сервера TLS перед началом рукопожатия TLS. Также, эта
SSLEngineдолжна быть настроена с параметрами, совместимыми с протоколом приложения, выбранным функцией обратного вызова. Например, включение плохого выбора наборов шифров может привести к отсутствию подходящего протокола приложения. См.SSLParameters. - Требования к реализации:
- Реализация в этом классе выбрасывает
UnsupportedOperationExceptionи не выполняет никаких других действий. - Параметры:
-
selector— функция обратного вызова или null для отключения функциональности обратного вызова. - Исключения:
-
UnsupportedOperationException— если базовый поставщик не реализует операцию. - С:
- 9
getHandshakeApplicationProtocolSelector
public BiFunction<SSLEngine, List<String>, String> getHandshakeApplicationProtocolSelector()
setHandshakeApplicationProtocolSelector для параметров типа функции.- Требования к реализации:
- Реализация в этом классе выбрасывает
UnsupportedOperationExceptionи не выполняет никаких других действий. - Возвращает:
- функцию обратного вызова или null, если она не была установлена.
- Исключения:
-
UnsupportedOperationException— если базовый поставщик не реализует операцию. - С:
- 9
© 1993, 2025, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://download.java.net/java/early_access/jdk24/docs/api/java.base/javax/net/ssl/SSLEngine.html