Класс 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 и традиционные Input/OutputStreams, локальные 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 могут потребоваться результаты задач, выполнение которых занимает длительное время или даже может блокироваться. Например, TrustManager может потребоваться подключиться к удаленной службе проверки сертификатов, а KeyManager может потребоваться запросить у пользователя, какой сертификат использовать для аутентификации клиента. Кроме того, создание и проверка криптографических подписей могут выполняться медленно и создавать впечатление блокировки.
Для любой операции, которая потенциально может блокироваться, SSLEngine создаст делегированную задачу Runnable. Когда SSLEngineResult указывает, что требуется результат делегированной задачи, приложение должно вызвать getDelegatedTask(), чтобы получить ожидающую выполнения делегированную задачу, и вызвать ее метод run() (при необходимости в другом потоке, в зависимости от стратегии вычислений). Приложению следует получать делегированные задачи, пока они не закончатся, а затем повторить исходную операцию.
По окончании сеанса связи приложениям следует надлежащим образом закрыть соединение SSL/TLS/DTLS. В протоколах SSL/TLS/DTLS предусмотрены сообщения рукопожатия для закрытия соединения; эти сообщения следует передать узлу взаимодействия до освобождения SSLEngine и закрытия базового транспортного механизма. Закрытие может быть инициировано одним из следующих событий: SSLException, входящим сообщением рукопожатия для закрытия или одним из методов закрытия. Во всех случаях сообщения рукопожатия для закрытия создаются движком, и wrap() следует вызывать повторно, пока состояние результирующего SSLEngineResult не станет «CLOSED» или пока isOutboundDone() не вернет true. Все данные, полученные методом wrap(), следует отправить узлу взаимодействия.
Метод closeOutbound() используется, чтобы сообщить движку, что приложение больше не будет отправлять данные.
Узел взаимодействия сообщает о намерении закрыть соединение, отправляя собственное сообщение рукопожатия для закрытия. После получения и обработки этого сообщения вызовом unwrap() у локального SSLEngine приложение может обнаружить закрытие, вызвав unwrap() и проверив, имеет ли SSLEngineResult состояние «CLOSED», либо проверив, возвращает ли 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()), поскольку невозможно гарантировать порядок отправки пакетов.
- Версия:
- 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() |
Возвращает используемый в этом SSLEngine объект SSLSession. |
SSLParameters |
getSSLParameters() |
Возвращает параметры SSL, действующие для этого 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 |
Применяет параметры SSL к этому движку. |
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—ByteBuffer, содержащий исходящие данные приложения -
dst—ByteBufferдля хранения исходящих сетевых данных - Возвращает:
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—ByteBufferдля хранения исходящих сетевых данных - Возвращает:
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—ByteBufferдля хранения исходящих сетевых данных - Возвращает:
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—ByteBuffer, содержащий входящие сетевые данные. -
dst—ByteBufferдля хранения входящих данных приложения. - Возвращает:
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—ByteBuffer, содержащий входящие сетевые данные. -
dsts— массивByteBufferдля хранения входящих данных приложения. - Возвращает:
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 этот метод может потреблять сетевые данные, не создавая данных приложения (например, он может потреблять данные рукопожатия).
Приложение отвечает за надёжное получение сетевых данных от партнёра и за вызов unwrap() для данных в порядке их получения. Приложение должно надлежащим образом синхронизировать несколько вызовов этого метода.
Если это SSLEngine ещё не начало начальное рукопожатие, данный метод запустит его автоматически.
Этот метод попытается потребить один полный сетевой пакет SSL/TLS/DTLS, но никогда не потребит больше, чем суммарное количество оставшихся байтов во всех буферах. Позиция каждого ByteBuffer обновляется с учётом объёма потреблённых или созданных данных. Ограничения остаются неизменными.
Области памяти, используемые src и dsts ByteBuffer, не должны совпадать.
Входящий сетевой буфер src может быть изменён в результате этого вызова. Поэтому, если сетевой пакет данных нужен для другой цели, перед вызовом этого метода следует создать его дубликат. Примечание: сетевые данные нельзя будет использовать повторно с другим SSLEngine, поскольку каждый SSLEngine содержит уникальное случайное состояние, влияющее на сообщения SSL/TLS/DTLS.
Дополнительные сведения о закрытии механизма см. в описании класса.
- Параметры:
-
src—ByteBuffer, содержащий входящие сетевые данные. -
dsts— массивByteBufferдля хранения входящих данных приложения. -
offset— смещение в массиве буферов, указывающее на первый буфер, в который будут передаваться байты; оно должно быть неотрицательным и не превышатьdsts.length. -
length— максимальное число буферов, к которым будет выполнен доступ; оно должно быть неотрицательным и не превышатьdsts.length-offset. - Возвращает:
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(), то при некоторых обстоятельствах инициатору не требуется ждать соответствующего сообщения о закрытии от партнёра. (Дополнительные сведения об ожидании уведомлений о закрытии см. в разделе 7.2.1 спецификации TLS (RFC 2246).) В таких случаях вызывать этот метод не требуется.
Однако если приложение не инициировало процесс закрытия или указанные выше обстоятельства неприменимы, этот метод следует вызвать при достижении конца потока данных SSL/TLS/DTLS. Это обеспечивает закрытие входящей стороны и проверяет, что партнёр надлежащим образом выполнил процедуру закрытия SSL/TLS/DTLS, позволяя обнаружить возможные атаки с усечением данных.
Этот метод идемпотентен: если входящая сторона уже закрыта, метод ничего не делает.
Для сброса оставшихся данных рукопожатия следует вызвать wrap().
- Вызывает:
-
SSLException— если этот механизм не получил от партнёра надлежащее сообщение об уведомлении о закрытии SSL/TLS/DTLS. - Внешние спецификации
- См. также:
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 может формировать данные рукопожатия для закрытия, которые необходимо отправить партнёру. Для создания этих данных необходимо вызвать wrap(). Когда этот метод возвращает true, исходящие данные больше создаваться не будут.
- Возвращает:
- true, если
SSLEngineбольше не будет создавать сетевые данные - См. также:
getSupportedCipherSuites
public abstract String[] getSupportedCipherSuites()
Возвращаемый массив включает наборы шифров из списка стандартных имён наборов шифров в разделе Имена наборов шифров JSSE спецификации Java Security Standard Algorithm Names, а также может содержать другие наборы шифров, поддерживаемые поставщиком.
- Возвращает:
- массив имён наборов шифров
- Внешние спецификации
- См. также:
getEnabledCipherSuites
public abstract String[] getEnabledCipherSuites()
Обратите внимание, что даже включённый набор может никогда не использоваться. Это может произойти, если партнёр его не поддерживает, его использование ограничено, отсутствуют необходимые для набора сертификаты (и закрытые ключи) или включён анонимный набор, но требуется аутентификация.
Возвращаемый массив включает наборы шифров из списка стандартных имён наборов шифров в разделе Имена наборов шифров JSSE спецификации Java Security Standard Algorithm Names, а также может содержать другие наборы шифров, поддерживаемые поставщиком.
- Возвращает:
- массив имён наборов шифров
- Внешние спецификации
- См. также:
setEnabledCipherSuites
public abstract void setEnabledCipherSuites(String[] suites)
Каждый набор шифров в параметре suites должен быть указан методом getSupportedCipherSuites(), иначе вызов метода завершится ошибкой. После успешного вызова этого метода будут включены для использования только наборы, перечисленные в параметре suites.
Обратите внимание, что стандартный список имён наборов шифров приведён в разделе Имена наборов шифров JSSE спецификации Java Security Standard Algorithm Names. Поставщики могут поддерживать имена наборов шифров, отсутствующие в этом списке, или использовать для некоторых наборов шифров имена, отличающиеся от рекомендуемых.
Дополнительные сведения о том, почему конкретный набор шифров может никогда не использоваться механизмом, см. в описании 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()
SSLSession, используемый этим SSLEngine. Эти сеансы могут существовать длительное время и часто соответствуют целому сеансу входа пользователя в систему. Сеанс задаёт конкретный набор шифров, активно используемый всеми подключениями в этом сеансе, а также идентификаторы клиента и сервера сеанса.
В отличие от SSLSocket.getSession(), этот метод не блокирует выполнение до завершения рукопожатия.
До завершения начального рукопожатия этот метод возвращает объект сеанса, указывающий недопустимый набор шифров "SSL_NULL_WITH_NULL_NULL".
- Возвращает:
SSLSessionдля этогоSSLEngine- См. также:
getHandshakeSession
public SSLSession getHandshakeSession()
SSLSession, создаваемый во время рукопожатия SSL/TLS/DTLS. При согласовании параметров протоколы 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, если для изменения режима на true не используется
setUseClientMode(boolean). - Возвращает:
- 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>- Второй аргумент функции содержит список имён протоколов приложений, объявленных узлом-партнёром TLS.
String- Результат функции — имя протокола приложения или null, указывающий, что ни одно из объявленных имён не подходит. Если возвращаемое значение — пустое
String, указания протоколов приложений использоваться не будут. Если возвращаемое значение равно null (значение не выбрано) или не было объявлено узлом-партнёром, базовый протокол определит дальнейшие действия. (Например, 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://docs.oracle.com/en/java/javase/25/docs/api/java.base/javax/net/ssl/SSLEngine.html