Класс SSLEngine
public abstract class SSLEngine extends Object
Режимы безопасного общения включают:
- Защита целостности. SSL/TLS/DTLS защищает от модификации сообщений активным перехватом.
- Аутентификация. В большинстве режимов SSL/TLS/DTLS обеспечивает аутентификацию участников. Серверы обычно аутентифицируются, а клиенты могут аутентифицироваться по запросу серверов.
- Конфиденциальность (защита конфиденциальности). В большинстве режимов SSL/TLS/DTLS шифрует данные, передаваемые между клиентом и сервером. Это защищает конфиденциальность данных, поэтому пассивные перехватывающие устройства не увидят конфиденциальные данные, такие как финансовая или личная информация.
Использование набора шифров осуществляется процессом согласования, называемым «рукопожатием». Цель этого процесса — создать или возобновить «сеанс», который может защищать множество соединений со временем. После завершения рукопожатия вы можете получить доступ к атрибутам сеанса, используя метод getSession().
Класс SSLSocket предоставляет большую часть той же функциональности безопасности, но все входящие и исходящие данные автоматически передаются с использованием базового Socket, который по умолчанию использует блокирующий режим. Хотя это подходит для многих приложений, этот режим не обеспечивает масштабируемость, необходимую для крупных серверов.
Основное отличие SSLEngine заключается в том, что он работает с входными и выходными байтовыми потоками, независимо от механизма транспорта. Пользователь SSLEngine отвечает за организацию надежной транспортной системы ввода-вывода с удалённым узлом. Разделяя абстракцию SSL/TLS/DTLS от механизма транспортного средства ввода-вывода, SSLEngine может использоваться для различных типов ввода-вывода, таких как non-blocking I/O (polling), selectable non-blocking I/O, Socket и традиционные потоки ввода/вывода, локальные ByteBuffers или массивы байтов, будущие асинхронные модели ввода-вывода и так далее.
В общих чертах, SSLEngine выглядит так:
app data
| ^
| | |
v | |
+----+-----|-----+----+
| | |
| SSL|Engine |
wrap() | | | unwrap()
| OUTBOUND | INBOUND |
| | |
+----+-----|-----+----+
| | ^
| | |
v |
net data
Данные приложения (также известные как текстовые данные или открытый текст) — это данные, которые производятся или потребляются приложением. Его аналог — сетевые данные, которые состоят либо из данных рукопожатия и/или зашифрованных данных и предназначены для передачи через механизм ввода-вывода. Входящие данные — это данные, полученные от удаленного узла, а исходящие данные предназначены для удаленного узла. (В контексте SSLEngine, термин «данные рукопожатия» понимается как любые данные, обмениваемые для установления и управления защищенным соединением. Данные рукопожатия включают сообщения SSL/TLS/DTLS «alert», «change_cipher_spec» и «handshake».)
Для SSLEngine существует пять различных фаз.
- Создание —
SSLEngineсоздан и инициализирован, но еще не используется. На этом этапе приложение может установить любые параметры, специфичные дляSSLEngine(активные наборы шифров, должен лиSSLEngineвыполнять рукопожатие в режиме клиента или сервера и т. д.). Однако после начала рукопожатия любые новые параметры (кроме режима клиента/сервера, см. ниже) будут использоваться для следующего рукопожатия. - Инициализация рукопожатия — первоначальное рукопожатие — это процедура, посредством которой два узла обмениваются параметрами связи до установления SSLSession. Приложение не может отправлять данные приложения на этом этапе.
- Данные приложения — после того, как параметры связи были установлены, и рукопожатие завершено, данные приложения могут проходить через
SSLEngine. Исходящие сообщения приложения зашифровываются и защищаются по целостности, а входящие сообщения выполняют обратный процесс. - Переговоры — любая сторона может запросить повторное согласование сеанса в любое время во время фазы данных приложения. Новые данные рукопожатия могут быть смешаны с данными приложения. Перед началом фазы повторного согласования приложение может сбросить параметры связи SSL/TLS/DTLS, такие как список включенных наборов шифров и использование аутентификации клиента, но не может изменить между режимами клиент/сервер. Как и прежде, после начала рукопожатия любые новые настройки конфигурации
SSLEngineне будут использоваться до следующего рукопожатия. - Закрытие — когда соединение больше не требуется, приложения клиента и сервера должны закрыть обе стороны своих соответствующих соединений. Для объектов
SSLEngineприложение должно вызватьcloseOutbound()и отправить все оставшиеся сообщения удалённому узлу. Аналогично, приложение должно принять все оставшиеся сообщения от удалённого узла перед вызовомcloseInbound(). После того, как обе стороныSSLEngineбудут закрыты, можно закрыть базовый механизм транспорта. Если соединение не закрыто должным образом (например,closeInbound()вызывается до получения уведомления о закрытии записи от удалённого узла), будут подняты исключения для указания возникновения ошибки. После закрытия движка он не может быть повторно использован: необходимо создать новыйSSLEngine.
SSLEngine создаётся путём вызова SSLContext.createSSLEngine() из инициализированного SSLContext. Любые параметры конфигурации должны быть установлены до первого вызова wrap(), unwrap() или beginHandshake(). Эти методы все запускают начальное рукопожатие. Данные перемещаются через движок путём вызова wrap() или unwrap() для исходящих или входящих данных соответственно. В зависимости от состояния SSLEngine, вызов wrap() может использовать данные приложения из исходного буфера и может генерировать сетевые данные в буфере назначения. Исходящие данные могут содержать данные приложения и/или рукопожатия. Вызов unwrap() проверит исходный буфер и может продвинуть рукопожатие, если данные являются информацией о рукопожатии, или поместить данные приложения в буфер назначения, если данные являются данными приложения. Состояние базового алгоритма SSL/TLS/DTLS определит, когда данные потребляются и генерируются.
Вызовы wrap() и unwrap() возвращают SSLEngineResult, который указывает статус операции и (по желанию) как взаимодействовать с движком для его продвижения.
SSLEngine производит/потребляет только полные пакеты SSL/TLS/DTLS и не хранит данные приложения во внутреннем хранилище между вызовами wrap()/unwrap(). Таким образом, входные и выходные ByteBuffer должны иметь размер, достаточный для хранения максимального пакета, который может быть произведён. Для определения соответствующих размеров буферов следует использовать вызовы SSLSession.getPacketBufferSize() и SSLSession.getApplicationBufferSize(). Размер буфера исходящих данных приложения обычно не имеет значения. Если условия буфера не позволяют должным образом потреблять/генерировать данные, приложение должно определить (через SSLEngineResult) и исправить проблему, а затем повторить вызов.
Например, unwrap() вернёт результат SSLEngineResult.Status.BUFFER_OVERFLOW, если движок определит, что недостаточно места в буфере назначения. Приложения должны вызвать SSLSession.getApplicationBufferSize() и сравнить это значение с имеющимся пространством в буфере назначения, увеличив буфер при необходимости. Аналогично, если unwrap() вернёт SSLEngineResult.Status.BUFFER_UNDERFLOW, приложение должно вызвать SSLSession.getPacketBufferSize() для обеспечения наличия достаточного места в исходном буфере для записи (увеличить при необходимости) и затем получить больше входных данных.
SSLEngineResult r = engine.unwrap(src, dst);
switch (r.getStatus()) {
case BUFFER_OVERFLOW:
// Could attempt to drain the dst buffer of any already obtained
// data, but we'll just increase it to the size needed.
int appSize = engine.getSession().getApplicationBufferSize();
ByteBuffer b = ByteBuffer.allocate(appSize + dst.position());
dst.flip();
b.put(dst);
dst = b;
// retry the operation.
break;
case BUFFER_UNDERFLOW:
int netSize = engine.getSession().getPacketBufferSize();
// Resize buffer if needed.
if (netSize > src.capacity()) {
ByteBuffer b = ByteBuffer.allocate(netSize);
src.flip();
b.put(src);
src = b;
}
// Obtain more inbound network data for src,
// then retry the operation.
break;
// other cases: CLOSED, OK.
}
В отличие от SSLSocket, все методы SSLEngine не блокирующие. Реализации SSLEngine могут потребовать результаты задач, выполнение которых может занять значительное время или даже заблокироваться. Например, TrustManager может потребоваться подключиться к удалённой службе проверки сертификатов, или KeyManager может потребоваться попросить пользователя определить сертификат, который нужно использовать в рамках аутентификации клиента. Кроме того, создание и проверка криптографических подписей может быть медленным и, похоже, блокирующим процессом.
Для любой операции, которая потенциально может заблокировать выполнение, SSLEngine создаст делегированную задачу Runnable. Когда SSLEngineResult укажет, что требуется результат делегированной задачи, приложение должно вызвать getDelegatedTask() для получения ожидающей делегированной задачи и вызвать её метод run() (возможно, используя другой поток в зависимости от стратегии вычисления). Приложение должно продолжать получать делегированные задачи до тех пор, пока они не закончатся, и повторить исходную операцию.
В конце сеанса связи приложения должны должным образом закрыть связь SSL/TLS/DTLS. Протоколы SSL/TLS/DTLS имеют сообщения рукопожатия закрытия, и эти сообщения должны быть переданы удалённому узлу перед высвобождением SSLEngine и закрытием базового механизма транспорта. Закрытие может быть инициировано одним из следующих способов: SSLException, сообщение об окончании рукопожатия, полученное с помощью входящего потока, или одним из методов закрытия. В любом случае сообщения рукопожатия закрытия генерируются движком, и wrap() должно вызываться повторно до тех пор, пока состояние возвращаемого SSLEngineResult не станет «CLOSED», или isOutboundDone() не вернёт true. Все данные, полученные из метода wrap() должны быть отправлены удалённому узлу.
closeOutbound() используется для сигнализации движку о том, что приложение больше не будет отправлять данные.
Узел сигнализирует о намерении закрыться, отправив собственное сообщение рукопожатия закрытия. После получения и обработки этого сообщения локальным SSLEngine's unwrap() вызовом, приложение может обнаружить закрытие, вызвав unwrap() и поиска статуса "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")) {
...
}
Приложения могут выбрать обработку делегированных задач в разных потоках. Когда создается SSLEngine, текущий AccessControlContext сохраняется. Все последующие делегированные задачи будут обрабатываться с использованием этого контекста: то есть, все решения по контролю доступа будут приниматься с использованием контекста, захваченного при создании движка.
- Методы
wrap()иunwrap()могут выполняться параллельно друг другу. - Протоколы SSL/TLS/DTLS используют упорядоченные пакеты. Приложения должны позаботиться о том, чтобы сгенерированные пакеты доставлялись последовательно. Если пакеты приходят в неупорядоченном порядке, могут возникнуть непредвиденные или фатальные результаты.
Например:
synchronized (outboundLock) { sslEngine.wrap(src, dst); outboundQueue.put(dst); }Как следствие, два потока не должны пытаться вызвать один и тот же метод (либоwrap()илиunwrap()) одновременно, потому что нет способа гарантировать конечную упорядоченность пакетов.
- Since:
- 1.5
- See Also:
Краткое описание конструкторов
| Модификатор | Конструктор | Описание |
|---|---|---|
protected |
Конструктор для SSLEngine, не предоставляющий подсказок для стратегии повторного использования внутренних сессий. |
|
protected |
Конструктор для SSLEngine. |
Краткое описание методов
| Модификатор и тип | Метод | Описание |
|---|---|---|
abstract void |
beginHandshake() |
Инициализирует рукопожатие (начальное или повторное) для этого SSLEngine. |
abstract void |
closeInbound() |
Указывает, что больше нет входных сетевых данных, которые будут отправлены в этот SSLEngine. |
abstract void |
closeOutbound() |
Указывает, что больше нет исходящих данных приложения, которые будут отправлены по этому SSLEngine. |
String |
getApplicationProtocol() |
Возвращает последнее значение протокола приложения, согласованное для этого соединения. |
abstract Runnable |
getDelegatedTask() |
Возвращает делегированную задачу Runnable для этого SSLEngine. |
abstract String[] |
getEnabledCipherSuites() |
Возвращает имена наборов шифрования SSL, которые в настоящее время включены для использования в этом модуле. |
abstract String[] |
getEnabledProtocols() |
Возвращает имена версий протоколов, которые в настоящее время включены для использования с этим SSLEngine. |
abstract boolean |
getEnableSessionCreation() |
Возвращает true, если новые сеансы SSL могут быть установлены этим модулем. |
String |
getHandshakeApplicationProtocol() |
Возвращает значение протокола приложения, согласованное во время текущего процесса рукопожатия SSL/TLS. |
BiFunction |
getHandshakeApplicationProtocolSelector() |
Извлекает функцию обратного вызова, которая выбирает значение протокола приложения во время рукопожатия SSL/TLS/DTLS. |
SSLSession |
getHandshakeSession() |
Возвращает SSLSession, создаваемый во время рукопожатия SSL/TLS/DTLS. |
abstract SSLEngineResult.HandshakeStatus |
getHandshakeStatus() |
Возвращает текущий статус рукопожатия для этого SSLEngine. |
abstract boolean |
getNeedClientAuth() |
Возвращает true, если модуль будет требовать аутентификации клиента. |
String |
getPeerHost() |
Возвращает имя хоста удаленного узла. |
int |
getPeerPort() |
Возвращает номер порта удаленного узла. |
abstract SSLSession |
getSession() |
Возвращает используемые SSLSession в этом SSLEngine. |
SSLParameters |
getSSLParameters() |
Возвращает используемые SSLParameters для этого SSLEngine. |
abstract String[] |
getSupportedCipherSuites() |
Возвращает имена наборов шифрования, которые могут быть включены для использования в этом модуле. |
abstract String[] |
getSupportedProtocols() |
Возвращает имена протоколов, которые могут быть включены для использования с этим SSLEngine. |
abstract boolean |
getUseClientMode() |
Возвращает true, если модуль настроен на использование клиентского режима во время рукопожатия. |
abstract boolean |
getWantClientAuth() |
Возвращает true, если модуль будет запрашивать аутентификацию клиента. |
abstract boolean |
isInboundDone() |
Возвращает, будет ли unwrap(ByteBuffer, ByteBuffer) принимать дополнительные сообщения входных данных. |
abstract boolean |
isOutboundDone() |
Возвращает, будет ли wrap(ByteBuffer, ByteBuffer) генерировать дополнительные сообщения выходных данных. |
abstract void |
setEnabledCipherSuites |
Устанавливает наборы шифрования, включенные для использования в этом модуле. |
abstract void |
setEnabledProtocols |
Устанавливает версии протоколов, включенные для использования в этом модуле. |
abstract void |
setEnableSessionCreation |
Управляет тем, могут ли быть созданы новые сеансы SSL этим модулем. |
void |
setHandshakeApplicationProtocolSelector |
Регистрирует функцию обратного вызова, которая выбирает значение протокола приложения для рукопожатия SSL/TLS/DTLS. |
abstract void |
setNeedClientAuth |
Настраивает модуль на требование аутентификации клиента. |
void |
setSSLParameters |
Применяет SSLParameters к этому модулю. |
abstract void |
setUseClientMode |
Настраивает модуль для использования клиентского (или серверного) режима при рукопожатии. |
abstract void |
setWantClientAuth |
Настраивает модуль на запрос аутентификации клиента. |
SSLEngineResult |
unwrap |
Попытка декодирования сетевых данных SSL/TLS/DTLS в буфер данных приложения в формате обычного текста. |
SSLEngineResult |
unwrap |
Попытка декодирования сетевых данных SSL/TLS/DTLS в последовательность буферов данных приложения в формате обычного текста. |
abstract SSLEngineResult |
unwrap |
Попытка декодирования сетевых данных SSL/TLS/DTLS в подпоследовательность буферов данных приложения в формате обычного текста. |
abstract SSLEngineResult |
wrap |
Попытка кодирования байтов обычного текста из подпоследовательности буферов данных в сетевые данные SSL/TLS/DTLS. |
SSLEngineResult |
wrap |
Попытка кодирования байтов обычного текста из последовательности буферов данных в сетевые данные SSL/TLS/DTLS. |
SSLEngineResult |
wrap |
Попытка кодирования буфера данных приложения в формате обычного текста в сетевые данные SSL/TLS/DTLS. |
Подробное описание конструкторов
SSLEngine
protected SSLEngine()
SSLEngine, не предоставляющий подсказок для стратегии повторного использования внутренней сессии.- См. также:
SSLEngine
protected SSLEngine(String peerHost, int peerPort)
SSLEngine. SSLEngine реализации могут использовать параметры peerHost и peerPort в качестве подсказок для своей внутренней стратегии повторного использования сеансов.
Некоторые наборы шифров (такие как Kerberos) требуют информации о удалённом имени хоста. Реализации этого класса должны использовать этот конструктор для использования Kerberos.
Параметры не аутентифицируются SSLEngine.
- Параметры:
-
peerHost- имя хоста удалённого узла -
peerPort- номер порта удалённого узла - См. также:
Подробное описание методов
getPeerHost
public String getPeerHost()
Обратите внимание, что значение не аутентифицировано и на него не следует полагаться.
- Возвращает:
- имя хоста удалённого узла, или null, если нет доступной информации.
getPeerPort
public int getPeerPort()
Обратите внимание, что значение не аутентифицировано и на него не следует полагаться.
- Возвращает:
- номер порта удалённого узла, или -1, если нет доступной информации.
wrap
public SSLEngineResult wrap(ByteBuffer src, ByteBuffer dst) throws SSLException
Вызов этого метода ведёт себя точно так же, как вызов:
engine.wrap(new ByteBuffer[] { src }, 0, 1, dst);
- Параметры:
-
src- буфер с исходящими данными приложения -
dst- буфер для хранения исходящих сетевых данных - Возвращает:
- объект, описывающий результат операции.
- Исключения:
-
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- массив буферов с исходящими данными приложения -
dst- буфер для хранения исходящих сетевых данных - Возвращает:
- объект, описывающий результат операции.
- Исключения:
-
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- массив буферов с исходящими данными приложения -
offset- Смещение в массиве буферов первого буфера, из которого будут извлекаться байты; оно должно быть неотрицательным и не больше, чемsrcs.length -
length- Максимальное количество буферов для доступа; оно должно быть неотрицательным и не больше, чемsrcs.length-offset -
dst- буфер для хранения исходящих сетевых данных - Возвращает:
- объект, описывающий результат операции.
- Исключения:
-
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- буфер с входящими сетевыми данными. -
dst- буфер для хранения входящих данных приложения. - Возвращает:
- объект, описывающий результат операции.
- Исключения:
-
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);
- Parameters:
-
src- aByteBuffer, содержащий входящие данные сети. -
dsts- массивByteBufferдля хранения входящих данных приложения. - Returns:
- a
SSLEngineResult, описывающий результат этой операции. - Throws:
-
SSLException- Возникла проблема при обработке данных, которая привела к прерываниюSSLEngine. См. описание класса для получения дополнительной информации о закрытии движка. -
ReadOnlyBufferException- если любой из буферовdstявляется только для чтения. -
IllegalArgumentException- еслиsrcилиdstsравно null, или если любой элемент вdstsравен null. -
IllegalStateException- если режим клиент/сервер ещё не установлен. - See Also:
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.
См. описание класса для получения дополнительной информации о закрытии движка.
- Parameters:
-
src- aByteBuffer, содержащий входящие данные сети. -
dsts- массивByteBufferдля хранения входящих данных приложения. -
offset- Смещение в массиве буферов первого буфера, из которого будут переданы байты; оно должно быть неотрицательным и не большеdsts.length. -
length- Максимальное количество буферов для доступа; оно должно быть неотрицательным и не большеdsts.length-offset. - Returns:
- a
SSLEngineResult, описывающий результат этой операции. - Throws:
-
SSLException- Возникла проблема при обработке данных, которая привела к прерываниюSSLEngine. См. описание класса для получения дополнительной информации о закрытии движка. -
IndexOutOfBoundsException- Если предварительные условия дляoffsetиlengthпараметров не соблюдаются. -
ReadOnlyBufferException- если любой из буферовdstявляется только для чтения. -
IllegalArgumentException- еслиsrcилиdstsравно null, или если любой элемент в подпоследовательностиdstsуказанной подпоследовательности равен null. -
IllegalStateException- если режим клиент/сервер ещё не установлен. - See Also:
getDelegatedTask
public abstract Runnable getDelegatedTask()
Runnable для этого SSLEngine. Операции SSLEngine могут потребовать результатов блокирующих операций или могут занимать значительное время для завершения. Этот метод используется для получения ожидающей операции Runnable (задачи). Каждой задаче должен быть назначен поток (возможно, текущий) для выполнения операции run. После возвращения метода run, объект Runnable больше не нужен и может быть удалён.
Делегированные задачи выполняются в AccessControlContext в том же месте, что и при создании этого объекта.
Вызов этого метода вернёт каждую ожидающую задачу ровно один раз.
Несколько делегированных задач могут выполняться параллельно.
- Returns:
- делегированная задача
Runnable, или null, если таких задач нет.
closeInbound
public abstract void closeInbound() throws SSLException
SSLEngine. Если приложение инициировало процесс закрытия, вызвав closeOutbound(), в некоторых случаях от инициатора не требуется ожидать соответствующего сообщения о закрытии от удалённого узла. (См. раздел 7.2.1 спецификации TLS (RFC 2246) для получения дополнительной информации об ожидании предупреждений о закрытии). В таких случаях этот метод вызывать не требуется.
Но если приложение не инициировало процесс закрытия или если вышеупомянутые условия не выполняются, этот метод следует вызывать всякий раз, когда достигается конец потока данных SSL/TLS/DTLS. Это гарантирует закрытие входящей стороны и проверяет, что удалённый узел правильно выполнил процедуру закрытия SSL/TLS/DTLS, тем самым обнаруживая возможные атаки обрезания.
Этот метод идемпотентен: если входящая сторона уже закрыта, этот метод ничего не делает.
wrap() следует вызвать для сброса любых оставшихся данных рукопожатия.
- Throws:
-
SSLException- если этот движок не получил надлежащего сообщения о закрытии SSL/TLS/DTLS от удалённого узла. - See Also:
isInboundDone
public abstract boolean isInboundDone()
unwrap(ByteBuffer, ByteBuffer) принимать дальнейшие входящие сообщения.- Returns:
- true, если
SSLEngineне будет потреблять больше сетевых данных (и, следовательно, не будет производить больше данных приложения). - See Also:
closeOutbound
public abstract void closeOutbound()
SSLEngine. Этот метод идемпотентен: если исходящая сторона уже закрыта, этот метод ничего не делает.
wrap(ByteBuffer, ByteBuffer) следует вызвать для сброса любых оставшихся данных рукопожатия.
- See Also:
isOutboundDone
public abstract boolean isOutboundDone()
wrap(ByteBuffer, ByteBuffer) производить дальнейшие исходящие сообщения. Обратите внимание, что на фазе закрытия SSLEngine может генерировать данные закрытия рукопожатия, которые необходимо отправить удалённому узлу. wrap() необходимо вызвать для генерации этих данных. Когда этот метод возвращает true, больше не будет создаваться исходящих данных.
- Returns:
- true, если
SSLEngineне будет производить больше сетевых данных - See Also:
getSupportedCipherSuites
public abstract String[] getSupportedCipherSuites()
Возвращаемый массив включает наборы шифрования из списка стандартных имён наборов шифрования в разделе JSSE Cipher Suite Names спецификации Java Security Standard Algorithm Names, а также может включать и другие наборы шифрования, поддерживаемые поставщиком.
- Возвращает:
- массив имён наборов шифрования
- См. также:
getEnabledCipherSuites
public abstract String[] getEnabledCipherSuites()
Обратите внимание, что даже если набор включён, он может никогда не использоваться. Это может произойти, если этого набора не поддерживает удалённый узел, или его использование ограничено, или требуемые сертификаты (и закрытые ключи) для набора недоступны, или анонимный набор включён, но требуется аутентификация.
Возвращаемый массив включает наборы шифрования из списка стандартных имён наборов шифрования в разделе JSSE Cipher Suite Names спецификации Java Security Standard Algorithm Names, а также может включать и другие наборы шифрования, поддерживаемые поставщиком.
- Возвращает:
- массив имён наборов шифрования
- См. также:
setEnabledCipherSuites
public abstract void setEnabledCipherSuites(String[] suites)
Каждый набор шифрования в параметре suites должен был быть перечислен в getSupportedCipherSuites(), иначе метод завершится неудачей. После успешного вызова этого метода, только наборы, указанные в параметре suites, включены для использования.
Обратите внимание, что стандартный список имён наборов шифрования можно найти в разделе JSSE Cipher Suite Names спецификации 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- если один или несколько протоколов, указанных в параметре, не поддерживаются, или если параметр протоколов равен 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- если подчинённый поставщик не реализует операцию. - C момента:
- 1.7
- См. также:
beginHandshake
public abstract void beginHandshake() throws SSLException
Этот метод не нужен для первоначального рукопожатия, так как методы wrap() и unwrap() неявно вызовут этот метод, если рукопожатие ещё не началось.
Обратите внимание, что удалённый узел также может запросить повторное рукопожатие с этим SSLEngine путём отправки соответствующего сообщения о повторном рукопожатии сессии.
В отличие от метода SSLSocket#startHandshake(), этот метод не блокируется до завершения рукопожатия.
Для принудительного полного повторного рукопожатия сессии SSL/TLS/DTLS текущая сессия должна быть аннулирована перед вызовом этого метода.
Некоторые протоколы могут не поддерживать несколько рукопожатий в одном движке и могут выбросить SSLException.
- Исключение:
-
SSLException- если при попытке запроситьSSLEngineначать новое рукопожатие возникла проблема. См. описание класса для получения дополнительной информации о закрытии движка. -
IllegalStateException- если режим клиента/сервера ещё не задан. - См. также:
getHandshakeStatus
public abstract SSLEngineResult.HandshakeStatus getHandshakeStatus()
SSLEngine.- Возвращает:
- текущий
SSLEngineResult.HandshakeStatus.
setUseClientMode
public abstract void setUseClientMode(boolean mode)
Этот метод должен быть вызван до любого рукопожатия. После начала рукопожатия режим не может быть изменён для этого движка.
Серверы обычно сами авторизуются, а клиенты не обязаны этого делать.
- Замечание по реализации:
- По умолчанию в реализации JDK SunJSSE поставщик для этого режима имеет значение false.
- Параметры:
-
mode- true, если движок должен начать рукопожатие в режиме "клиент" - Исключения:
-
IllegalArgumentException- если попытка изменения режима производится после начала начального рукопожатия. - См. также:
getUseClientMode
public abstract boolean getUseClientMode()
- Замечание по реализации:
- Реализация JDK SunJSSE поставщика возвращает false, если
setUseClientMode(boolean)не используется для изменения режима на true. - Возвращает:
- true, если движок должен выполнить рукопожатие в режиме "клиент"
- См. также:
setNeedClientAuth
public abstract void setNeedClientAuth(boolean need)
Настройка аутентификации клиента для движка может быть одной из следующих:
- требуется аутентификация клиента
- запрашивается аутентификация клиента
- аутентификация клиента не требуется
В отличие от setWantClientAuth(boolean), если этот параметр установлен, и клиент отказывается предоставить информацию об авторизации, переговоры прекратятся, и движок начнёт процедуру закрытия.
Вызов этого метода переопределяет любые предыдущие настройки, сделанные этим методом или setWantClientAuth(boolean).
- Параметры:
-
need- устанавливается в true, если требуется аутентификация клиента, или в false, если аутентификация клиента не требуется. - См. также:
getNeedClientAuth
public abstract boolean getNeedClientAuth()
- Возвращает:
- true, если требуется аутентификация клиента, или false, если она не требуется.
- См. также:
setWantClientAuth
public abstract void setWantClientAuth(boolean want)
Настройка аутентификации клиента для движка может быть одной из следующих:
- требуется аутентификация клиента
- запрашивается аутентификация клиента
- аутентификация клиента не требуется
В отличие от setNeedClientAuth(boolean), если этот параметр установлен, и клиент отказывается предоставить информацию об авторизации, переговоры продолжатся.
Вызов этого метода переопределяет любые предыдущие настройки, сделанные этим методом или setNeedClientAuth(boolean).
- Параметры:
-
want- устанавливается в true, если запрашивается аутентификация клиента, или в false, если она не требуется. - См. также:
getWantClientAuth
public abstract boolean getWantClientAuth()
- Возвращает:
- true, если запрашивается аутентификация клиента, или false, если она не требуется.
- См. также:
setEnableSessionCreation
public abstract void setEnableSessionCreation(boolean flag)
- Параметры:
-
flag- true указывает, что сессии могут быть созданы; это значение по умолчанию. false указывает, что должна быть возобновлена существующая сессия - См. также:
getEnableSessionCreation
public abstract boolean getEnableSessionCreation()
- Возвращает:
- true указывает, что сессии могут быть созданы; это значение по умолчанию. false указывает, что должна быть возобновлена существующая сессия
- См. также:
getSSLParameters
public SSLParameters getSSLParameters()
- Возвращает:
- SSLParameters, действующие для этого SSLEngine.
- С:
- 1.6
setSSLParameters
public void setSSLParameters(SSLParameters params)
Это означает:
- Если
params.getCipherSuites()не равно null,setEnabledCipherSuites()вызывается с этим значением. - Если
params.getProtocols()не равно null,setEnabledProtocols()вызывается с этим значением. - Если
params.getNeedClientAuth()илиparams.getWantClientAuth()возвращаютtrue,setNeedClientAuth(true)иsetWantClientAuth(true)вызываются соответственно; в противном случае вызываетсяsetWantClientAuth(false). - Если
params.getServerNames()не равно null, движок настроит свои имена сервера с этим значением. - Если
params.getSNIMatchers()не равно null, движок настроит свои SNI-совпадения с этим значением.
- Параметры:
-
params- параметры - Исключения:
-
IllegalArgumentException- если вызов setEnabledCipherSuites() или setEnabledProtocols() завершается неудачно - С:
- 1.6
getApplicationProtocol
public String getApplicationProtocol()
Если поддерживается основой SSL/TLS/DTLS реализацией, механизмы переговоров имени приложения, такие как RFC 7301, протокол переговоров прикладного уровня (ALPN), могут договариваться о значениях на уровне приложения между узлами.
- Требования к реализации:
- Реализация в этом классе выбрасывает
UnsupportedOperationExceptionи не выполняет никаких других действий. - Возвращает:
- null, если ещё не определено, будут ли использоваться протоколы приложения для этого соединения; пустая строка
String, если протоколы приложения не будут использоваться, или непустой протокол приложенияString, если значение было успешно согласовано. - Исключения:
-
UnsupportedOperationException- если базовый поставщик не реализует операцию. - С:
- 9
getHandshakeApplicationProtocol
public String getHandshakeApplicationProtocol()
Подобно getHandshakeSession(), соединение может находиться посредине рукопожатия. Протокол приложения может или ещё не быть доступен.
- Требования к реализации:
- Реализация в этом классе выбрасывает
UnsupportedOperationExceptionи не выполняет никаких других действий. - Возвращает:
- null, если ещё не определено, будут ли использоваться протоколы приложения для этого рукопожатия; пустая строка
String, если протоколы приложения не будут использоваться, или непустой протокол приложенияString, если значение было успешно согласовано. - Исключения:
-
UnsupportedOperationException- если базовый поставщик не реализует операцию. - С:
- 9
Установка селектора протокола приложения для рукопожатия
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
Получение селектора протокола приложения для рукопожатия
public BiFunction<SSLEngine,List<String>,String> getHandshakeApplicationProtocolSelector()
setHandshakeApplicationProtocolSelector для параметров типа функции.- Требования к реализации:
- Реализация в этом классе выбрасывает
UnsupportedOperationExceptionи не выполняет никаких других действий. - Возвращает:
- функцию обратного вызова или null, если она не установлена.
- Исключения:
-
UnsupportedOperationException- если базовый поставщик не реализует операцию. - С момента:
- 9
© 1993, 2023, 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/21/docs/api/java.base/javax/net/ssl/SSLEngine.html