- java.lang.Object
-
- javax.net.ssl.SSLEngine
-
public abstract class SSLEngine extends Object
使用安全套接字层(SSL)或IETF RFC 2246 "Transport Layer Security" (TLS)协议等协议实现安全通信但与传输无关的类。安全通信模式包括:
- 诚信保护 。 SSL / TLS / DTLS可防止活动窃听器修改消息。
- 身份验证 在大多数模式下,SSL / TLS / DTLS提供对等身份验证。 服务器通常经过身份验证,客户端可以按服务器的请求进行身份验证。
- 保密(隐私保护) 。 在大多数模式下,SSL / TLS / DTLS会加密客户端和服务器之间发送的数据。 这样可以保护数据的机密性,使被动窃听器不会看到敏感数据,如财务信息或多种个人信息。
使用的密码套件由称为“握手”的协商过程建立。 此过程的目标是创建或重新加入“会话”,这可能会随着时间的推移保护许多连接。 握手完成后,您可以使用
getSession()
方法访问会话属性。SSLSocket
类提供了大部分相同的安全功能,但所有入站和出站数据都是使用基础Socket
自动传输的,该设计使用了阻塞模型。 虽然这适用于许多应用程序,但此模型不提供大型服务器所需的可伸缩性。SSLEngine
的主要区别在于它对入站和出站字节流进行操作,与传输机制无关。SSLEngine
用户有责任为对等SSLEngine
安排可靠的I / O传输。 通过分离SSL / TLS / DTLS从I / O传输机制抽象化,所述SSLEngine
可用于各种各样的I / O类型的,例如non-blocking I/O (polling)
,selectable non-blocking I/O
,Socket
和传统的输入/ OutputStreams,本地ByteBuffers
或字节数组, future asynchronous I/O models等。在较高的水平,
SSLEngine
因此出现:app data | ^ | | | v | | +----+-----|-----+----+ | | | | SSL|Engine | wrap() | | | unwrap() | OUTBOUND | INBOUND | | | | +----+-----|-----+----+ | | ^ | | | v | net data
应用程序数据(也称为明文或明文)是由应用程序生成或使用的数据。 它的对应物是网络数据,它由握手和/或密文(加密)数据组成,并且通过I / O机制传输。 入站数据是从对等方接收的数据,出站数据以对等方为目的地。(在
SSLEngine
的上下文中,术语“握手数据”用于表示为建立和控制安全连接而交换的任何数据。握手数据包括SSL / TLS / DTLS消息“alert”,“change_cipher_spec”和“握手” “。)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()) { 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; BUFFER_UNDERFLOW: int netSize = engine.getSession().getPacketBufferSize(); // Resize buffer if needed. if (netSize > dst.capacity()) { ByteBuffer b = ByteBuffer.allocate(netSize); src.flip(); b.put(src); src = b; } // Obtain more inbound network data for src, // then retry the operation. break; // other cases: CLOSED, OK. }
与
SSLSocket
不同,SSLEngine的所有方法都是非阻塞的。SSLEngine
实现可能需要可能需要较长时间才能完成的任务结果,SSLEngine
可能需要阻止。 例如,TrustManager可能需要连接到远程证书验证服务,或者KeyManager可能需要提示用户确定将哪个证书用作客户端身份验证的一部分。 此外,创建加密签名并验证它们可能很慢,看似阻塞。对于可能阻止的任何操作,
SSLEngine
将创建Runnable
委派任务。 当SSLEngineResult
指示需要委派的任务结果时,应用程序必须调用getDelegatedTask()
以获取未完成的委派任务并调用其run()
方法(可能使用不同的线程,具体取决于计算策略)。 应用程序应继续获取委派任务,直到不再存在,并再次尝试原始操作。在通信会话结束时,应用程序应正确关闭SSL / TLS / DTLS链接。 SSL / TLS / DTLS协议具有闭包握手消息,在释放
SSLEngine
并关闭底层传输机制之前,应将这些消息传递给对等体。 可以通过以下之一启动关闭:SSLException,入站闭包握手消息或其中一种close方法。 在所有情况下,由发动机产生的关闭握手报文,并wrap()
直至所得应被重复调用SSLEngineResult
的状态返回‘关闭’,或isOutboundDone()
返回true。 从wrap()
方法获得的所有数据都应发送给对等方。closeOutbound()
用于向引擎发出信号,表明应用程序将不再发送任何数据。对等体将通过发送其自己的闭包握手消息来发出关闭意图。 此消息已被接收和处理的地方后
SSLEngine
的unwrap()
调用,应用程序可以检测关闭,通过调用unwrap()
和寻找SSLEngineResult
状态为‘关闭’,或者如果isInboundDone()
返回true。 如果由于某种原因,对等方在没有发送正确的SSL / TLS / DTLS关闭消息的情况下关闭通信链路,则应用程序可以检测到流末端并且可以通过closeInbound()
向引擎发出信号,表示将不再有要处理的入站消息。 某些应用程序可能会选择要求来自对等方的有序关闭消息,在这种情况下,它们可以检查闭包是由握手消息生成的,而不是由流末尾条件生成的。在管理密码套件时,您需要了解两组密码套件:
- 支持的密码套件:SSL实现支持的所有套件。 此列表使用
getSupportedCipherSuites()
报告。 - 启用密码套件,可能少于全套支持套件。 使用
setEnabledCipherSuites(String [])
方法设置该组,并使用getEnabledCipherSuites()
方法查询。 最初,将在代表最小建议配置的新引擎上启用一组默认密码套件。
每个SSL / TLS / DTLS连接必须有一个客户端和一个服务器,因此每个端点必须决定要承担哪个角色。 该选择决定了谁开始握手过程以及每一方应该发送哪种类型的消息。 方法
setUseClientMode(boolean)
配置模式。 初始握手开始后,即使执行重新协商,SSLEngine
也无法在客户端和服务器模式之间切换。应用程序可能会选择在不同的线程中处理委派的任务。 当
SSLEngine
创建,目前AccessControlContext
保存。 将使用此上下文处理所有将来的委派任务:即,将使用在引擎创建时捕获的上下文来做出所有访问控制决策。
并发注意事项 :有两个并发问题需要注意:-
wrap()
和unwrap()
方法可以彼此同时执行。 - SSL / TLS / DTLS协议使用有序数据包。 应用程序必须注意确保生成的数据包按顺序传递。 如果数据包无序到达,可能会发生意外或致命的结果。
例如:
synchronized (outboundLock) { sslEngine.wrap(src, dst); outboundQueue.put(dst); }
作为推论,两个线程不能同时尝试调用相同的方法(wrap()
或unwrap()
),因为无法保证最终的数据包排序。
- 从以下版本开始:
- 1.5
- 另请参见:
-
SSLContext
,SSLSocket
,SSLServerSocket
,SSLSession
,Socket
-
-
方法摘要
所有方法 实例方法 抽象方法 具体的方法 变量和类型 方法 描述 abstract void
beginHandshake()
在此SSLEngine上启动握手(初始或重新协商)。abstract void
closeInbound()
表示不再向此SSLEngine
发送入站网络数据。abstract void
closeOutbound()
表示将不再在此SSLEngine
上发送出站应用程序数据。String
getApplicationProtocol()
返回为此连接协商的最新应用程序协议值。abstract Runnable
getDelegatedTask()
返回此SSLEngine
的委派Runnable
任务。abstract String[]
getEnabledCipherSuites()
返回当前启用以在此引擎上使用的SSL密码套件的名称。abstract String[]
getEnabledProtocols()
返回当前启用以与此SSLEngine
一起使用的协议版本的名称。abstract boolean
getEnableSessionCreation()
如果此引擎可以建立新的SSL会话,则返回true。String
getHandshakeApplicationProtocol()
返回当前正在进行的SSL / TLS握手协商的应用程序协议值。BiFunction<SSLEngine,List<String>,String>
getHandshakeApplicationProtocolSelector()
检索在SSL / TLS / DTLS握手期间选择应用程序协议值的回调函数。SSLSession
getHandshakeSession()
返回在SSL / TLS / DTLS握手期间构造的SSLSession
。abstract SSLEngineResult.HandshakeStatus
getHandshakeStatus()
返回此SSLEngine
的当前握手状态。abstract boolean
getNeedClientAuth()
如果引擎 需要客户端身份验证,则返回true。String
getPeerHost()
返回对等方的主机名。int
getPeerPort()
返回对等体的端口号。abstract SSLSession
getSession()
返回SSLSession
中使用的SSLEngine
。SSLParameters
getSSLParameters()
返回对此SSLEngine有效的SSLParameters。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(String[] suites)
设置启用此引擎的密码套件。abstract void
setEnabledProtocols(String[] protocols)
设置启用此引擎的协议版本。abstract void
setEnableSessionCreation(boolean flag)
控制是否可以由此引擎建立新的SSL会话。void
setHandshakeApplicationProtocolSelector(BiFunction<SSLEngine,List<String>,String> selector)
注册一个回调函数,为SSL / TLS / DTLS握手选择应用程序协议值。abstract void
setNeedClientAuth(boolean need)
配置引擎以 要求客户端身份验证。void
setSSLParameters(SSLParameters params)
将SSLParameters应用于此引擎。abstract void
setUseClientMode(boolean mode)
配置引擎在握手时使用客户端(或服务器)模式。abstract void
setWantClientAuth(boolean want)
配置引擎以 请求客户端身份验证。SSLEngineResult
unwrap(ByteBuffer src, ByteBuffer dst)
尝试将SSL / TLS / DTLS网络数据解码为纯文本应用程序数据缓冲区。SSLEngineResult
unwrap(ByteBuffer src, ByteBuffer[] dsts)
尝试将SSL / TLS / DTLS网络数据解码为一系列明文应用程序数据缓冲区。abstract SSLEngineResult
unwrap(ByteBuffer src, ByteBuffer[] dsts, int offset, int length)
尝试将SSL / TLS / DTLS网络数据解码为明文应用程序数据缓冲区的子序列。abstract SSLEngineResult
wrap(ByteBuffer[] srcs, int offset, int length, ByteBuffer dst)
尝试将明文字节从数据缓冲区的子序列编码为SSL / TLS / DTLS网络数据。SSLEngineResult
wrap(ByteBuffer[] srcs, ByteBuffer dst)
尝试将明文字节从一系列数据缓冲区编码为SSL / TLS / DTLS网络数据。SSLEngineResult
wrap(ByteBuffer src, ByteBuffer dst)
尝试将明文应用程序数据缓冲区编码为SSL / TLS / DTLS网络数据。
-
-
-
构造方法详细信息
-
SSLEngine
protected SSLEngine()
SSLEngine
构造函数不提供内部会话重用策略的提示。
-
SSLEngine
protected SSLEngine(String peerHost, int peerPort)
SSLEngine
构造SSLEngine
。SSLEngine
实现可以使用peerHost
和peerPort
参数作为其内部会话重用策略的提示。某些密码套件(例如Kerberos)需要远程主机名信息。 此类的实现应使用此构造函数来使用Kerberos。
SSLEngine
未对参数进行身份验证。- 参数
-
peerHost
- 对等主机的名称 -
peerPort
- 对等体的端口号 - 另请参见:
-
SSLContext.createSSLEngine(String, int)
,SSLSessionContext
-
-
方法详细信息
-
getPeerHost
public String getPeerHost()
返回对等方的主机名。请注意,该值未经过身份验证,因此不应依赖该值。
- 结果
- 对等体的主机名,如果没有可用的则为null。
-
getPeerPort
public int getPeerPort()
返回对等体的端口号。请注意,该值未经过身份验证,因此不应依赖该值。
- 结果
- 对等体的端口号,如果没有可用的话,则为-1。
-
wrap
public SSLEngineResult wrap(ByteBuffer src, ByteBuffer dst) throws SSLException
尝试将明文应用程序数据缓冲区编码为SSL / TLS / DTLS网络数据。调用此方法的行为与调用完全相同:
engine.wrap(new ByteBuffer [] { src }, 0, 1, dst);
- 参数
-
src
- 包含出站应用程序数据的ByteBuffer
-
dst
- 用于保存出站网络数据的ByteBuffer
- 结果
-
描述此操作结果的
SSLEngineResult
。 - 异常
-
SSLException
- 处理导致SSLEngine
中止的数据时遇到问题。 有关引擎关闭的更多信息,请参阅类描述。 -
ReadOnlyBufferException
- 如果dst
缓冲区是只读的。 -
IllegalArgumentException
- 如果src
或dst
为空。 -
IllegalStateException
- 如果尚未设置客户端/服务器模式。 - 另请参见:
-
wrap(ByteBuffer [], int, int, ByteBuffer)
-
wrap
public SSLEngineResult wrap(ByteBuffer[] srcs, ByteBuffer dst) throws SSLException
- 参数
-
srcs
- 包含出站应用程序数据的ByteBuffers
数组 -
dst
- 用于保存出站网络数据的ByteBuffer
- 结果
-
描述此操作结果的
SSLEngineResult
。 - 异常
-
SSLException
- 处理导致SSLEngine
中止的数据时遇到问题。 有关引擎关闭的更多信息,请参阅类描述。 -
ReadOnlyBufferException
- 如果dst
缓冲区是只读的。 -
IllegalArgumentException
- 如果srcs
或dst
为空,或者srcs
任何元素为空。 -
IllegalStateException
- 如果尚未设置客户端/服务器模式。 - 另请参见:
-
wrap(ByteBuffer [], int, int, ByteBuffer)
-
wrap
public abstract SSLEngineResult wrap(ByteBuffer[] srcs, int offset, int length, ByteBuffer dst) throws SSLException
尝试将明文字节从数据缓冲区的子序列编码为SSL / TLS / DTLS网络数据。 该“聚集”操作在单个调用中编码来自给定缓冲器序列中的一个或多个的字节序列。 在实现网络协议或文件格式时,收集包装通常很有用,例如,将数据分组为由一个或多个固定长度标头后跟可变长度主体组成的段。 见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
为空,或者指定的srcs
序列中的任何元素为null。 -
IllegalStateException
- 如果尚未设置客户端/服务器模式。 - 另请参见:
-
GatheringByteChannel
,GatheringByteChannel.write( ByteBuffer[], int, int)
-
unwrap
public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer dst) throws SSLException
尝试将SSL / TLS / DTLS网络数据解码为纯文本应用程序数据缓冲区。调用此方法的行为与调用完全相同:
engine.unwrap(src, new ByteBuffer [] { dst }, 0, 1);
- 参数
-
src
- 包含入站网络数据的ByteBuffer
。 -
dst
- 用于保存入站应用程序数据的ByteBuffer
。 - 结果
-
描述此操作结果的
SSLEngineResult
。 - 异常
-
SSLException
- 处理导致SSLEngine
中止的数据时遇到问题。 有关引擎关闭的更多信息,请参阅类描述。 -
ReadOnlyBufferException
- 如果dst
缓冲区是只读的。 -
IllegalArgumentException
- 如果src
或dst
为空。 -
IllegalStateException
- 如果尚未设置客户端/服务器模式。 - 另请参见:
-
unwrap(ByteBuffer, ByteBuffer [], int, int)
-
unwrap
public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts) throws SSLException
尝试将SSL / TLS / DTLS网络数据解码为一系列明文应用程序数据缓冲区。调用此方法的行为与调用完全相同:
engine.unwrap(src, dsts, 0, dsts.length);
- 参数
-
src
- 包含入站网络数据的ByteBuffer
。 -
dsts
- 用于保存入站应用程序数据的ByteBuffer
数组。 - 结果
-
描述此操作结果的
SSLEngineResult
。 - 异常
-
SSLException
- 处理导致SSLEngine
中止的数据时遇到问题。 有关引擎关闭的更多信息,请参阅类描述。 -
ReadOnlyBufferException
- 如果任何dst
缓冲区是只读的。 -
IllegalArgumentException
- 如果src
或dsts
为空,或者dsts
任何元素为空。 -
IllegalStateException
- 如果尚未设置客户端/服务器模式。 - 另请参见:
-
unwrap(ByteBuffer, ByteBuffer [], int, int)
-
unwrap
public abstract SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts, int offset, int length) throws SSLException
尝试将SSL / TLS / DTLS网络数据解码为明文应用程序数据缓冲区的子序列。 该“散射”操作在单个调用中将一个字节序列解码为一个或多个给定的缓冲器序列。 在实现网络协议或文件格式时,散布展开通常很有用,例如,将数据分组为由一个或多个固定长度标头后跟可变长度主体组成的段。 见ScatteringByteChannel
关于分散的更多信息,并ScatteringByteChannel.read(ByteBuffer[], int, int)
对序列行为的更多信息。根据SSLEngine的状态,此方法可能会消耗网络数据而不会生成任何应用程序数据(例如,它可能会消耗握手数据。)
应用程序负责从对等方可靠地获取网络数据,并按照接收顺序对数据调用unwrap()。 应用程序必须正确同步多个此方法的调用。
如果此
SSLEngine
尚未启动其初始握手,则此方法将自动启动握手。此方法将尝试使用一个完整的SSL / TLS / DTLS网络数据包,但绝不会消耗超过缓冲区中剩余字节数的总和。 每个
ByteBuffer
的位置都会更新,以反映消耗或生成的数据量。 限制保持不变。src
和dsts ByteBuffer
使用的基础内存不能相同。作为此调用的结果,可以修改入站网络缓冲区:因此,如果出于某些次要目的需要网络数据包,则应在调用此方法之前复制数据。 注意:网络数据对第二个SSLEngine没有用,因为每个SSLEngine都包含影响SSL / TLS / DTLS消息的唯一随机状态。
有关引擎关闭的更多信息,请参阅类描述。
- 参数
-
src
- 包含入站网络数据的ByteBuffer
。 -
dsts
- 用于保存入站应用程序数据的ByteBuffer
数组。 -
offset
- 第一个缓冲区的缓冲区数组中要从中传输字节的偏移量; 它必须是非负数且不大于dsts.length
。 -
length
- 要访问的最大缓冲区数; 它必须是非负数且不大于dsts.length
-offset
。 - 结果
-
描述此操作结果的
SSLEngineResult
。 - 异常
-
SSLException
- 处理导致SSLEngine
中止的数据时遇到问题。 有关引擎关闭的更多信息,请参阅类描述。 -
IndexOutOfBoundsException
- 如果offset
和length
参数的前提条件不成立。 -
ReadOnlyBufferException
- 如果dst
缓冲区中的任何一个是只读的。 -
IllegalArgumentException
- 如果src
或dsts
为空,或者指定的dsts
序列中的任何元素为null。 -
IllegalStateException
- 如果尚未设置客户端/服务器模式。 - 另请参见:
-
ScatteringByteChannel
,ScatteringByteChannel.read( ByteBuffer[], int, int)
-
getDelegatedTask
public abstract Runnable getDelegatedTask()
返回此SSLEngine
的委派Runnable
任务。SSLEngine
操作可能需要阻止或可能需要较长时间才能完成的操作结果。 此方法用于获得未完成的Runnable
操作(任务)。 必须为每个任务分配一个线程(可能是当前的)以执行run
操作。run
方法返回后,不再需要Runnable
对象,可以将其丢弃。创建此对象时,委派的任务在
AccessControlContext
中运行。对此方法的调用将仅返回每个未完成的任务一次。
可以并行运行多个委派任务。
- 结果
-
委派的
Runnable
任务,如果没有,Runnable
null。
-
closeInbound
public abstract void closeInbound() throws SSLException
表示不再向此网络数据发送SSLEngine
。如果应用程序通过调用
closeOutbound()
启动了关闭过程,则在某些情况下,启动程序不需要等待对等方的相应关闭消息。 (有关等待关闭警报的更多信息,请参阅TLS规范的第7.2.1节( RFC 2246 )。)在这种情况下,不需要调用此方法。但是,如果应用程序未启动关闭过程,或者上述情况不适用,则只要达到SSL / TLS / DTLS数据流的末尾,就应调用此方法。 这确保了入站端的关闭,并检查对等体是否正确遵循SSL / TLS / DTLS关闭过程,从而检测可能的截断攻击。
此方法是幂等的:如果入站端已经关闭,则此方法不执行任何操作。
应调用
wrap()
来刷新任何剩余的握手数据。- 异常
-
SSLException
- 如果此引擎未从对等方收到正确的SSL / TLS / DTLS关闭通知消息。 - 另请参见:
-
isInboundDone()
,isOutboundDone()
-
isInboundDone
public abstract boolean isInboundDone()
返回unwrap(ByteBuffer, ByteBuffer)
是否将接受任何其他入站数据消息。- 结果
-
如果
SSLEngine
不再消耗网络数据(并且暗示,将不再生成任何应用程序数据),SSLEngine
true。 - 另请参见:
-
closeInbound()
-
closeOutbound
public abstract void closeOutbound()
表示将不再在此SSLEngine
上发送出站应用程序数据。此方法是幂等的:如果出站端已经关闭,则此方法不执行任何操作。
应调用
wrap(ByteBuffer, ByteBuffer)
来刷新任何剩余的握手数据。- 另请参见:
-
isOutboundDone()
-
isOutboundDone
public abstract boolean isOutboundDone()
返回wrap(ByteBuffer, ByteBuffer)
是否将生成更多出站数据消息。请注意,在关闭阶段,
SSLEngine
可能会生成必须发送给对等方的握手闭包数据。 必须调用wrap()
才能生成此数据。 当此方法返回true时,将不再创建出站数据。- 结果
-
如果
SSLEngine
不再生成任何网络数据,SSLEngine
true - 另请参见:
-
closeOutbound()
,closeInbound()
-
getSupportedCipherSuites
public abstract String[] getSupportedCipherSuites()
返回可以在此引擎上启用的密码套件的名称。 通常,默认情况下实际上仅启用其中的一部分,因为此列表可能包括不符合这些默认值的服务质量要求的密码套件。 这种密码套件可能在专门的应用程序中很有用。返回的数组包括Java Cryptography体系结构标准算法名称文档的JSSE Cipher Suite Names部分中的标准密码套件名称列表中的密码套件,还可能包括提供程序支持的其他密码套件。
- 结果
- 一组密码套件名称
- 另请参见:
-
getEnabledCipherSuites()
,setEnabledCipherSuites(String [])
-
getEnabledCipherSuites
public abstract String[] getEnabledCipherSuites()
返回当前启用以在此引擎上使用的SSL密码套件的名称。 首次创建SSLEngine时,所有启用的密码套件都支持最低服务质量。 因此,在某些环境中,此值可能为空。请注意,即使启用了套件,也可能永远不会使用它。 如果对等方不支持它,或者它的使用受到限制,或者套件的必需证书(和私钥)不可用,或者启用了匿名套件但需要进行身份验证,则会发生这种情况。
返回的数组包括Java Cryptography体系结构标准算法名称文档的JSSE Cipher Suite Names部分中的标准密码套件名称列表中的密码套件,还可能包括提供程序支持的其他密码套件。
- 结果
- 一组密码套件名称
- 另请参见:
-
getSupportedCipherSuites()
,setEnabledCipherSuites(String [])
-
setEnabledCipherSuites
public abstract void setEnabledCipherSuites(String[] suites)
设置启用此引擎的密码套件。suites
参数中的每个密码套件必须已由getSupportedCipherSuites()列出,否则该方法将失败。 成功调用此方法后,仅启用suites
参数中列出的套件以供使用。请注意,密码套件名称的标准列表可以在Java Cryptography Architecture标准算法名称文档的JSSE Cipher Suite Names部分中找到。 提供商可能支持此列表中未找到的密码套件名称,或者可能不使用某个密码套件的建议名称。
有关为什么特定密码套件永远不会在引擎上使用的详细信息,请参见
getEnabledCipherSuites()
。- 参数
-
suites
- 要启用的所有密码套件的名称 - 异常
-
IllegalArgumentException
- 当不支持参数指定的一个或多个密码时,或者参数为null时。 - 另请参见:
-
getSupportedCipherSuites()
,getEnabledCipherSuites()
-
getSupportedProtocols
public abstract String[] getSupportedProtocols()
返回可以与此SSLEngine
一起使用的协议的名称。- 结果
- 支持的一系列协议
-
getEnabledProtocols
public abstract String[] getEnabledProtocols()
返回当前启用以与此SSLEngine
一起使用的协议版本的名称。请注意,即使启用了协议,也可能永远不会使用它。 如果对等方不支持协议,或者其使用受到限制,或者协议不支持启用的密码套件,则会发生这种情况。
- 结果
- 一系列协议
- 另请参见:
-
setEnabledProtocols(String [])
-
setEnabledProtocols
public abstract void setEnabledProtocols(String[] protocols)
设置启用此引擎的协议版本。这些协议必须由getSupportedProtocols()列为支持。 成功调用此方法后,仅启用
protocols
参数中列出的协议。- 参数
-
protocols
- 要启用的所有协议的名称。 - 异常
-
IllegalArgumentException
- 当不支持参数指定的一个或多个协议或者参数为null时。 - 另请参见:
-
getEnabledProtocols()
-
getSession
public abstract SSLSession getSession()
返回SSLSession
中使用的SSLEngine
。这些可以是长期存在的,并且经常对应于某些用户的整个登录会话。 会话指定特定的密码套件,该会话中的所有连接都在使用该密码套件,以及会话的客户端和服务器的身份。
与
SSLSocket.getSession()
不同,此方法在握手完成之前不会阻止。在初始握手完成之前,此方法返回一个会话对象,该对象报告无效的密码套件“SSL_NULL_WITH_NULL_NULL”。
- 结果
-
这个
SSLSession
的SSLEngine
- 另请参见:
-
SSLSession
-
getHandshakeSession
public SSLSession getHandshakeSession()
返回在SSL / TLS / DTLS握手期间构造的SSLSession
。TLS / DTLS协议可以在使用此类的实例时,但在
SSLSession
已完全初始化并通过getSession
提供之前协商所需的参数。 例如,有效签名算法列表可能会限制在TrustManager决策期间可以使用的证书类型,或者可以调整最大TLS / DTLS分段数据包大小以更好地支持网络环境。此方法提供对正在构建的
SSLSession
早期访问。 根据握手进展的程度,某些数据可能尚未可用。 例如,如果远程服务器将发送一个证书链,但链尚未没有被处理,则getPeerCertificates
的方法SSLSession
将抛出SSLPeerUnverifiedException。 处理getPeerCertificates
链后,getPeerCertificates
将返回正确的值。- 结果
-
如果此实例当前没有握手,或者当前握手的进度不足以创建基本SSLSession,则返回null。
否则,此方法返回当前正在协商的
SSLSession
。 - 异常
-
UnsupportedOperationException
- 如果基础提供程序未实现该操作。 - 从以下版本开始:
- 1.7
- 另请参见:
-
SSLSocket
,SSLSession
,ExtendedSSLSession
,X509ExtendedKeyManager
,X509ExtendedTrustManager
-
beginHandshake
public abstract void beginHandshake() throws SSLException
在此SSLEngine上启动握手(初始或重新协商)。初始握手不需要此方法,因为如果握手尚未开始,
wrap()
和unwrap()
方法将隐式调用此方法。请注意,对等方还可以通过发送相应的会话重新协商握手消息来请求与此
SSLEngine
进行会话重新协商。与
SSLSocket#startHandshake()
方法不同,此方法在握手完成之前不会阻止。要强制执行完整的SSL / TLS / DTLS会话重新协商,应在调用此方法之前使当前会话失效。
某些协议可能不支持在现有引擎上进行多次握手,并且可能会抛出
SSLException
。- 异常
-
SSLException
- 如果在发信号SSLEngine
开始新握手时遇到问题。 有关引擎关闭的更多信息,请参阅类描述。 -
IllegalStateException
- 如果尚未设置客户端/服务器模式。 - 另请参见:
-
SSLSession.invalidate()
-
getHandshakeStatus
public abstract SSLEngineResult.HandshakeStatus getHandshakeStatus()
返回此SSLEngine
的当前握手状态。- 结果
-
目前
SSLEngineResult.HandshakeStatus
。
-
setUseClientMode
public abstract void setUseClientMode(boolean mode)
配置引擎在握手时使用客户端(或服务器)模式。必须在进行任何握手之前调用此方法。 一旦握手开始,该模式就不能在该发动机的使用寿命内重置。
服务器通常对自己进行身份验证,并且客户端不需要这样做。
- 参数
-
mode
- 如果引擎应在“客户端”模式下开始握手,mode
true - 异常
-
IllegalArgumentException
- 如果在初始握手开始后尝试模式更改。 - 另请参见:
-
getUseClientMode()
-
getUseClientMode
public abstract boolean getUseClientMode()
如果在握手时将引擎设置为使用客户端模式,则返回true。- 结果
- 如果引擎应在“客户端”模式下进行握手,则为true
- 另请参见:
-
setUseClientMode(boolean)
-
setNeedClientAuth
public abstract void setNeedClientAuth(boolean need)
配置引擎以要求客户端身份验证。 此选项仅对服务器模式下的引擎有用。引擎的客户端身份验证设置是以下之一:
- 需要客户端验证
- 请求客户端身份验
- 无需客户端身份验证
与
setWantClientAuth(boolean)
不同,如果设置了此选项并且客户端选择不提供有关其自身的身份验证信息, 则协商将停止,引擎将开始其关闭过程 。调用此方法会覆盖此方法或
setWantClientAuth(boolean)
之前的任何设置。- 参数
-
need
- 如果需要客户端身份验证,则设置为true;如果不需要客户端身份验证,则设置为false。 - 另请参见:
-
getNeedClientAuth()
,setWantClientAuth(boolean)
,getWantClientAuth()
,setUseClientMode(boolean)
-
getNeedClientAuth
public abstract boolean getNeedClientAuth()
如果引擎需要客户端身份验证,则返回true。 此选项仅对服务器模式下的引擎有用。- 结果
- 如果需要客户端身份验证,则为true;如果不需要客户端身份验证,则为false
- 另请参见:
-
setNeedClientAuth(boolean)
,setWantClientAuth(boolean)
,getWantClientAuth()
,setUseClientMode(boolean)
-
setWantClientAuth
public abstract void setWantClientAuth(boolean want)
配置引擎以请求客户端身份验证。 此选项仅对服务器模式下的引擎有用。引擎的客户端身份验证设置是以下之一:
- 需要客户端验证
- 请求客户端身份验
- 无需客户端身份验证
与
setNeedClientAuth(boolean)
不同,如果设置了此选项并且客户端选择不提供有关其自身的身份验证信息, 则协商将继续 。调用此方法会覆盖此方法或
setNeedClientAuth(boolean)
之前的任何设置。- 参数
-
want
- 如果请求客户端身份验证,则设置为true;如果不需要客户端身份验证,则设置为false。 - 另请参见:
-
getWantClientAuth()
,setNeedClientAuth(boolean)
,getNeedClientAuth()
,setUseClientMode(boolean)
-
getWantClientAuth
public abstract boolean getWantClientAuth()
如果引擎将请求客户端身份验证,则返回true。 此选项仅对服务器模式下的引擎有用。- 结果
- 如果请求客户端身份验证,则为true;如果不需要客户端身份验证,则为false
- 另请参见:
-
setNeedClientAuth(boolean)
,getNeedClientAuth()
,setWantClientAuth(boolean)
,setUseClientMode(boolean)
-
setEnableSessionCreation
public abstract void setEnableSessionCreation(boolean flag)
控制是否可以由此引擎建立新的SSL会话。 如果不允许会话创建,并且没有现有会话要恢复,则不会有成功的握手。- 参数
-
flag
- true表示可以创建会话; 这是默认值。 false表示必须恢复现有会话 - 另请参见:
-
getEnableSessionCreation()
-
getEnableSessionCreation
public abstract boolean getEnableSessionCreation()
如果此引擎可以建立新的SSL会话,则返回true。- 结果
- true表示可以创建会话; 这是默认值。 false表示必须恢复现有会话
- 另请参见:
-
setEnableSessionCreation(boolean)
-
getSSLParameters
public SSLParameters getSSLParameters()
返回对此SSLEngine有效的SSLParameters。 返回的SSLParameters的密码套件和协议始终为非null。- 结果
- SSLParameters对此SSLEngine有效。
- 从以下版本开始:
- 1.6
-
setSSLParameters
public void setSSLParameters(SSLParameters params)
将SSLParameters应用于此引擎。这意味着:
- 如果
params.getCipherSuites()
为非null,则使用该值调用setEnabledCipherSuites()
。 - 如果
params.getProtocols()
非空,则使用该值调用setEnabledProtocols()
。 - 如果
params.getNeedClientAuth()
或params.getWantClientAuth()
回报true
,setNeedClientAuth(true)
和setWantClientAuth(true)
被称为,分别; 否则setWantClientAuth(false)
。 - 如果
params.getServerNames()
为非null,则引擎将使用该值配置其服务器名称。 - 如果
params.getSNIMatchers()
非空,则引擎将使用该值配置其SNI匹配器。
- 参数
-
params
- 参数 - 异常
-
IllegalArgumentException
- 如果setEnabledCipherSuites()或setEnabledProtocols()调用失败 - 从以下版本开始:
- 1.6
- 如果
-
getApplicationProtocol
public String getApplicationProtocol()
返回为此连接协商的最新应用程序协议值。如果基础SSL / TLS / DTLS实现支持,应用程序名称协商机制(如RFC 7301 ,应用程序层协议协商(ALPN))可以在对等方之间协商应用程序级别的值。
- 实现要求:
-
此类中的实现抛出
UnsupportedOperationException
并且不执行任何其他操作。 - 结果
-
如果尚未确定应用程序协议是否可用于此连接,则
String
如果不使用应用程序协议值,String
空String
如果成功协商了值,String
非空应用程序协议String
。 - 异常
-
UnsupportedOperationException
- 如果基础提供程序未实现该操作。 - 从以下版本开始:
- 9
-
getHandshakeApplicationProtocol
public String getHandshakeApplicationProtocol()
返回当前正在进行的SSL / TLS握手协商的应用程序协议值。与
getHandshakeSession()
一样,连接可能正在握手中。 应用程序协议可能已经或可能尚未提供。- 实现要求:
-
此类中的实现抛出
UnsupportedOperationException
并且不执行任何其他操作。 - 结果
-
如果尚未确定应用程序协议是否可用于此握手,则
String
如果不使用应用程序协议值,String
空String
如果成功协商了值,String
非空应用程序协议String
。 - 异常
-
UnsupportedOperationException
- 如果基础提供程序未实现该操作。 - 从以下版本开始:
- 9
-
setHandshakeApplicationProtocolSelector
public void setHandshakeApplicationProtocolSelector(BiFunction<SSLEngine,List<String>,String> selector)
注册一个回调函数,为SSL / TLS / DTLS握手选择应用程序协议值。 该函数将覆盖使用SSLParameters.setApplicationProtocols
提供的任何值,并且它支持以下类型参数:-
SSLEngine
-
The function's first argument allows the current
SSLEngine
to be inspected, including the handshake session and configuration settings. -
List<String>
- The function's second argument lists the application protocol names advertised by the TLS peer.
-
String
-
The function's result is an application protocol name, or null to indicate that none of the advertised names are acceptable. If the return value is an empty
String
then application protocol indications will not be used. If the return value is null (no value chosen) or is a value that was not advertised by the peer, the underlying protocol will determine what action to take. (For example, ALPN will send a "no_application_protocol" alert and terminate the connection.)
serverEngine.setHandshakeApplicationProtocolSelector( (serverEngine, clientProtocols) -> { SSLSession session = serverEngine.getHandshakeSession(); return chooseApplicationProtocol( serverEngine, clientProtocols, session.getProtocol(), session.getCipherSuite()); });
- API Note:
-
在TLS握手开始之前,应由TLS服务器应用程序调用此方法。
此外,应使用与回调函数选择的应用程序协议兼容的参数配置此
SSLEngine
。 例如,启用较差的密码套件选择可能导致没有合适的应用程序协议。 见SSLParameters
。 - 实现要求:
-
此类中的实现抛出
UnsupportedOperationException
并且不执行任何其他操作。 - 参数
-
selector
- 回调函数,或null以禁用回调功能。 - 异常
-
UnsupportedOperationException
- 如果基础提供程序未实现该操作。 - 从以下版本开始:
- 9
-
-
getHandshakeApplicationProtocolSelector
public BiFunction<SSLEngine,List<String>,String> getHandshakeApplicationProtocolSelector()
检索在SSL / TLS / DTLS握手期间选择应用程序协议值的回调函数。 有关函数的类型参数,请参见setHandshakeApplicationProtocolSelector
。- 实现要求:
-
此类中的实现抛出
UnsupportedOperationException
并且不执行任何其他操作。 - 结果
- 回调函数,如果没有设置则返回null。
- 异常
-
UnsupportedOperationException
- 如果基础提供程序未实现该操作。 - 从以下版本开始:
- 9
-
-