Класс 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. |
Методы, объявленные в классе Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait | Модификатор и тип | Метод | Описание |
|---|---|---|
protected Object |
clone() |
Создаёт и возвращает копию этого объекта. |
boolean |
equals |
Указывает, равен ли этот объект другому объекту. |
protected void |
finalize() |
Устарел и будет удалён: этот элемент API может быть удалён в будущей версии. Финализация устарела и может быть удалена в одном из будущих выпусков. |
final Class |
getClass() |
Возвращает класс времени выполнения этого Object. |
int |
hashCode() |
Возвращает хеш-код этого объекта. |
final void |
notify() |
Пробуждает один поток, ожидающий на мониторе этого объекта. |
final void |
notifyAll() |
Пробуждает все потоки, ожидающие на мониторе этого объекта. |
String |
toString() |
Возвращает строковое представление объекта. |
final void |
wait() |
Переводит текущий поток в состояние ожидания до пробуждения, обычно вследствие вызова метода notify или interrupt. |
final void |
wait |
Переводит текущий поток в состояние ожидания до пробуждения, обычно вследствие вызова метода notify или interrupt, либо до истечения заданного времени. |
final void |
wait |
Переводит текущий поток в состояние ожидания до пробуждения, обычно вследствие вызова метода notify или interrupt, либо до истечения заданного времени. |
Подробное описание конструкторов
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, а также может включать другие наборы шифров, поддерживаемые поставщиком.
- Возвращает:
- массив названий наборов шифров
- Внешние спецификации
- См. также:
getEnabledCipherSuites
public abstract String[] getEnabledCipherSuites()
Обратите внимание, что даже включённый набор может никогда не использоваться. Это может произойти, если партнёр его не поддерживает, его использование ограничено, отсутствуют необходимые для него сертификаты (и закрытые ключи) либо включён анонимный набор, но требуется аутентификация.
Возвращаемый массив включает наборы шифров из списка стандартных названий, приведённого в разделе Названия наборов шифров JSSE спецификации стандартных названий алгоритмов безопасности Java, а также может включать другие наборы шифров, поддерживаемые поставщиком.
- Возвращает:
- массив названий наборов шифров
- Внешние спецификации
- См. также:
setEnabledCipherSuites
public abstract void setEnabledCipherSuites(String[] suites)
Каждый набор шифров в параметре suites должен быть указан в списке, возвращаемом getSupportedCipherSuites(), иначе метод завершится с ошибкой. После успешного вызова этого метода для использования включаются только наборы, перечисленные в параметре suites.
Обратите внимание, что стандартный список названий наборов шифров приведён в разделе Названия наборов шифров JSSE спецификации стандартных названий алгоритмов безопасности Java. Поставщики могут поддерживать названия наборов шифров, отсутствующие в этом списке, или использовать для конкретного набора шифров название, отличное от рекомендованного.
Дополнительные сведения о причинах, по которым конкретный набор шифров может никогда не использоваться движком, см. в разделе 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 объект SSLSession. Срок их действия может быть длительным, и они часто соответствуют целому сеансу входа пользователя в систему. Сеанс определяет конкретный набор шифров, активно используемый всеми соединениями в этом сеансе, а также идентификаторы клиента и сервера сеанса.
В отличие от 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
SSLEngine. К распространенным причинам относятся необходимость инициировать новый защищенный сеанс, создать новые ключи шифрования или изменить наборы шифров. Чтобы принудительно выполнить полную повторную аутентификацию, перед началом этого рукопожатия следует сделать текущий сеанс недействительным.
Поведение этого метода зависит от протокола (и, возможно, от реализации). Например, в TLSv1.3 вызов этого метода после установления соединения приводит к обновлению ключей. В более ранних версиях TLS он приводит к повторному согласованию (повторному рукопожатию).
Этот метод не требуется для начального рукопожатия, поскольку методы wrap() и unwrap() неявно вызывают его, если рукопожатие еще не началось.
Обратите внимание, что узел-партнер также может запросить повторное согласование сеанса с этим SSLEngine, отправив соответствующее сообщение рукопожатия для повторного согласования сеанса.
В отличие от метода SSLSocket#startHandshake(), этот метод не блокирует выполнение до завершения рукопожатия.
Некоторые протоколы могут не поддерживать несколько рукопожатий в существующем движке и могут выбросить 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.