Класс 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() и поиска SSLEngineResult со статусом "CLOSED", или если isInboundDone() возвращает true. Если по какой-то причине узел закрывает канал связи, не отправив соответствующее сообщение о завершении SSL/TLS/DTLS, приложение может обнаружить конец потока и сигнализировать движку через closeInbound(), что больше не будет поступающих сообщений для обработки. Некоторые приложения могут потребовать упорядоченных сообщений о завершении от узла, в этом случае они могут проверить, было ли завершение вызвано сообщением о рукопожатии, а не состоянием конца потока.
Существуют две группы наборов шифров, о которых вам необходимо знать при управлении наборами шифров:
- Поддерживаемые наборы шифров: все наборы шифров, поддерживаемые реализацией SSL. Этот список сообщается с помощью
getSupportedCipherSuites(). - Включенные наборы шифров, которые могут быть меньше полного набора поддерживаемых наборов. Эта группа устанавливается с помощью метода
setEnabledCipherSuites(String [])и запрашивается с помощью методаgetEnabledCipherSuites(). Изначально на новом движке будет включен стандартный набор наборов шифров, представляющий минимальную рекомендуемую конфигурацию.
Каждое соединение SSL/TLS/DTLS должно иметь один клиент и один сервер, таким образом, каждый конечная точка должна выбрать, какую роль принять. Этот выбор определяет, кто начинает процесс рукопожатия, а также какой тип сообщений должен отправлять каждый участник. Метод setUseClientMode(boolean) настраивает режим. Обратите внимание, что режим по умолчанию для нового SSLEngine зависит от поставщика. Приложения должны явно установить режим перед вызовом других методов SSLEngine. После начала начального рукопожатия SSLEngine не может переключаться между режимами клиента и сервера, даже при переподключениях.
Значения ApplicationProtocol String, возвращаемые методами в этом классе, находятся в сетевом представлении байтов, отправленном узлом. Байты можно напрямую сравнивать или преобразовать в формат Unicode {code 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<SSLEngine, |
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-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);
- 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 не должна быть одинаковой.
Входящий сетевой буфер может быть изменён в результате этого вызова: поэтому, если пакет сетевых данных необходим для какой-либо вторичной цели, данные должны быть дублированы перед вызовом этого метода. Примечание: сетевые данные не будут полезны для другого 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 документации по стандартным именам алгоритмов Java Cryptography Architecture и может также включать другие наборы шифрования, поддерживаемые провайдером.
- Возвращает:
- массив имён наборов шифрования
- См. также:
getEnabledCipherSuites
public abstract String[] getEnabledCipherSuites()
Обратите внимание, что даже если набор включён, он может никогда не использоваться. Это может произойти, если его не поддерживает партнёр, или его использование ограничено, или необходимые сертификаты (и закрытые ключи) для набора недоступны, или анонимный набор включён, но требуется аутентификация.
Возвращаемый массив включает наборы шифрования из списка стандартных имён наборов шифрования в разделе Имена наборов шифрования JSSE документации по стандартным именам алгоритмов Java Cryptography Architecture и может также включать другие наборы шифрования, поддерживаемые провайдером.
- Возвращает:
- массив имён наборов шифрования
- См. также:
setEnabledCipherSuites
public abstract void setEnabledCipherSuites(String[] suites)
Каждый набор шифрования в параметре suites должен был быть перечислен getSupportedCipherSuites(), иначе метод завершится неудачно. После успешного вызова этого метода, только наборы, перечисленные в параметре suites, включены для использования.
Обратите внимание, что стандартный список имён наборов шифрования можно найти в разделе Имена наборов шифрования JSSE документации по стандартным именам алгоритмов Java Cryptography Architecture. Провайдеры могут поддерживать имена наборов шифрования, не найденные в этом списке, или могут не использовать рекомендованное имя для определённого набора шифрования.
Смотрите 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- если базовый поставщик не реализует операцию. - С:
- 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.
- C момента:
- 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() завершается ошибкой - C момента:
- 1.6
getApplicationProtocol
public String getApplicationProtocol()
Если это поддерживается реализацией SSL/TLS/DTLS, механизмы согласования имени приложения, такие как RFC 7301 , Протокол согласования приложения на уровне приложений (ALPN), могут согласовывать значения на уровне приложений между узлами.
- Требования реализации:
- Реализация в этом классе выбрасывает
UnsupportedOperationExceptionи не выполняет никаких других действий. - Возвращает:
- null, если ещё не определено, будут ли использоваться протоколы приложений для этого соединения; пустую строку, если протоколы приложений не будут использоваться, или непустой протокол приложения, если значение было успешно согласовано.
- Исключения:
-
UnsupportedOperationException- если базовый поставщик не реализует операцию. - C момента:
- 9
getHandshakeApplicationProtocol
public String getHandshakeApplicationProtocol()
Как и getHandshakeSession(), соединение может находиться в середине процесса установления соединения. Протокол приложения может или ещё не быть доступным.
- Требования реализации:
- Реализация в этом классе выбрасывает
UnsupportedOperationExceptionи не выполняет никаких других действий. - Возвращает:
- null, если ещё не определено, будут ли использоваться протоколы приложений для этого установления соединения; пустую строку, если протоколы приложений не будут использоваться, или непустой протокол приложения, если значение было успешно согласовано.
- Исключения:
-
UnsupportedOperationException- если базовый поставщик не реализует операцию. - C момента:
- 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, 2021, 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/17/docs/api/java.base/javax/net/ssl/SSLEngine.html