public abstract class SSLEngine
extends Object
java.lang.Object | |
↳ | javax.net.ssl.SSLEngine |
一种使用协议(如安全套接字层(SSL)或 IETF RFC 2246 "Transport Layer Security" (TLS)协议)实现安全通信的类,但是与传输无关。
安全通信模式包括:
所使用的密码套件由称为“握手”的协商过程建立。 此过程的目标是创建或重新加入“会话”,这可以保护许多连接随着时间的推移。 握手完成后,您可以使用getSession()
方法访问会话属性。
SSLSocket
类提供了大部分相同的安全功能,但所有入站和出站数据都使用底层Socket
自动传输,该设计使用了阻塞模型。 虽然这适用于许多应用程序,但该模型不能提供大型服务器所需的可扩展性。
SSLEngine
的主要区别在于它在入站和出站字节流上运行,与传输机制无关。 SSLEngine
用户有责任为对等SSLEngine
安排可靠的I / O传输。 通过从I / O传输机制中分离出SSL / TLS抽象,所述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 dataApplication data (also known as plaintext or cleartext) is data which is produced or consumed by an application. Its counterpart is network data, which consists of either handshaking and/or ciphertext (encrypted) data, and destined to be transported via an I/O mechanism. Inbound data is data which has been received from the peer, and outbound data is destined for the peer.
(在 SSLEngine
的背景下,术语“握手数据”被认为是指交换来建立和控制安全连接的任何数据。握手数据包括SSL / TLS消息“alert”,“change_cipher_spec”和“handshake”。 )
SSLEngine
有五个不同的阶段。
SSLEngine
has been created and initialized, but has not yet been used. During this phase, an application may set any SSLEngine
-specific settings (enabled cipher suites, whether the SSLEngine
should handshake in client or server mode, and so on). Once handshaking has begun, though, any new settings (except client/server mode, see below) will be used for the next handshake. SSLEngine
. Outbound application messages are encrypted and integrity protected, and inbound messages reverse the process. SSLEngine
configuration settings will not be used until the next handshake. SSLEngine
and should send/receive any remaining messages to the peer before closing the underlying transport mechanism. Once an engine is closed, it is not reusable: a new SSLEngine
must be created. SSLEngine
is created by calling
createSSLEngine()
from an initialized
SSLContext
. Any configuration parameters should be set before making the first call to
wrap()
,
unwrap()
, or
beginHandshake()
. These methods all trigger the initial handshake.
数据分别通过调用wrap()
或unwrap()
对出站或入站数据在引擎中移动。 根据SSLEngine
的状态, wrap()
调用可能会消耗源缓冲区中的应用程序数据,并可能在目标缓冲区中产生网络数据。 出站数据可能包含应用程序和/或握手数据。 对unwrap()
的调用将检查源缓冲区,并且如果数据是握手信息,则可以推进握手,或者如果数据是应用程序,则可以将应用程序数据放置在目标缓冲区中。 底层SSL / TLS算法的状态将决定何时消耗和生成数据。
调用 wrap()
和 unwrap()
返回一个 SSLEngineResult
,它指示操作的状态,以及(可选)如何与引擎交互以取得进展。
SSLEngine
生成/使用完整的SSL / TLS数据包,并且不会在调用wrap()/unwrap()
之间的内部存储应用程序数据。 因此,输入和输出ByteBuffer
的大小必须适当,以保持可产生的最大记录。 应使用调用getPacketBufferSize()
和getApplicationBufferSize()
来确定适当的缓冲区大小。 出站应用程序数据缓冲区的大小通常无关紧要。 如果缓冲区条件不允许正确的数据消耗/生成,应用程序必须确定(通过SSLEngineResult
)并纠正问题,然后再次尝试呼叫。
例如,如果引擎确定没有足够的可用目标缓冲区空间,则unwrap()
将返回BUFFER_OVERFLOW
结果。 应用程序应该调用getApplicationBufferSize()
,并将该值与目标缓冲区中可用的空间进行比较,如有必要,可以放大缓冲区。 同样,如果unwrap()
要返回BUFFER_UNDERFLOW
,则应用程序应调用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
实现可能需要可能需要较长时间才能完成的任务的结果,甚至可能会阻塞。 例如,TrustManager可能需要连接到远程证书验证服务,或者KeyManager可能需要提示用户确定使用哪个证书作为客户端身份验证的一部分。 此外,创建加密签名并验证它们可能会很慢,看似阻塞。
对于任何可能阻塞的操作, SSLEngine
将创建一个Runnable
委派任务。 当SSLEngineResult
指示需要委派的任务结果时,应用程序必须调用getDelegatedTask()
以获取未完成的委托任务并调用其run()
方法(可能使用不同的线程,具体取决于计算策略)。 应用程序应该继续获得委托任务,直到不存在为止,然后再次尝试原始操作。
在通信会话结束时,应用程序应该正确关闭SSL / TLS链接。 SSL / TLS协议具有关闭握手消息,并且在释放SSLEngine
并关闭底层传输机制之前应将这些消息传递给对等体。 关闭可以由以下之一发起:SSLException,入站关闭握手消息或其中一种关闭方法。 在所有情况下,由发动机产生的关闭握手报文,并wrap()
直至所得应被重复调用SSLEngineResult
‘封闭’的状态返回,或isOutboundDone()
返回true。 从wrap()
方法获得的所有数据都应发送给对等方。
closeOutbound()
用于向引擎发信号表示应用程序不会再发送任何数据。
对等体将通过发送自己的闭包握手消息来表明其关闭的意图。 此消息已被接收和处理的地方后SSLEngine
的unwrap()
调用,应用程序可以检测关闭,通过调用unwrap()
并寻找SSLEngineResult
状态为‘关闭’,或者如果isInboundDone()
返回true。 如果由于某种原因,对端关闭通信链路而没有发送正确的SSL / TLS关闭消息,则应用程序可以检测到流结束,并且可以通过closeInbound()
向引擎发送没有更多入站消息要处理的信号。 某些应用程序可能会选择要求从对等方有序关闭消息,在这种情况下,他们可以检查闭包是由握手消息生成的,而不是由流结束条件生成的。
有两组密码套件,您在管理密码套件时需要了解这些套件:
getSupportedCipherSuites()
. setEnabledCipherSuites(String[])
method, and queried using the getEnabledCipherSuites()
method. Initially, a default set of cipher suites will be enabled on a new engine that represents the minimum suggested configuration. 每个SSL / TLS连接必须有一个客户端和一个服务器,因此每个端点必须决定承担哪个角色。 这种选择决定了谁开始握手过程以及每个参与方应该发送哪种类型的消息。 方法setUseClientMode(boolean)
配置模式。 一旦初始握手开始,即使在执行重新协商时, SSLEngine
也不能在客户端和服务器模式之间切换。
应用程序可能会选择在不同线程中处理委派的任务。 当创建SSLEngine
,当前的AccessControlContext
被保存。 所有未来的委托任务都将使用此上下文进行处理:也就是说,所有访问控制决策都将使用在引擎创建时捕获的上下文进行。
wrap()
and unwrap()
methods may execute concurrently of each other. 例如:
synchronized (outboundLock) { sslEngine.wrap(src, dst); outboundQueue.put(dst); }As a corollary, two threads must not attempt to call the same method (either
wrap()
or unwrap()
) concurrently, because there is no way to guarantee the eventual packet ordering. 从默认 SSLContext
获得的 SSLEngine
实例配置如下:
Protocol | Supported (API Levels) | Enabled by default (API Levels) |
---|---|---|
SSLv3 | 1+ | 1–22 |
TLSv1 | 1+ | 1+ |
TLSv1.1 | 20+ | 20+ |
TLSv1.2 | 20+ | 20+ |
Cipher suite | Supported (API Levels) | Enabled by default (API Levels) |
---|---|---|
SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA | 9–22 | 9–19 |
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA | 9–22 | 9–19 |
SSL_DHE_DSS_WITH_DES_CBC_SHA | 9–22 | 9–19 |
SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA | 9–22 | 9–19 |
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA | 9–22 | 9–19 |
SSL_DHE_RSA_WITH_DES_CBC_SHA | 9–22 | 9–19 |
SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA | 9–22 | |
SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 | 9–22 | |
SSL_DH_anon_WITH_3DES_EDE_CBC_SHA | 9–22 | |
SSL_DH_anon_WITH_DES_CBC_SHA | 9–22 | |
SSL_DH_anon_WITH_RC4_128_MD5 | 9–22 | |
SSL_RSA_EXPORT_WITH_DES40_CBC_SHA | 9–22 | 9–19 |
SSL_RSA_EXPORT_WITH_RC4_40_MD5 | 9–22 | 9–19 |
SSL_RSA_WITH_3DES_EDE_CBC_SHA | 9+ | 9–19 |
SSL_RSA_WITH_DES_CBC_SHA | 9–22 | 9–19 |
SSL_RSA_WITH_NULL_MD5 | 9–22 | |
SSL_RSA_WITH_NULL_SHA | 9–22 | |
SSL_RSA_WITH_RC4_128_MD5 | 9+ | 9–19 |
SSL_RSA_WITH_RC4_128_SHA | 9+ | 9–23 |
TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA | 1–8 | 1–8 |
TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA | 1–8 | 1–8 |
TLS_DHE_DSS_WITH_AES_128_CBC_SHA | 9–22 | 9–22 |
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 | 20–22 | |
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 | 20–22 | |
TLS_DHE_DSS_WITH_AES_256_CBC_SHA | 9–22 | 20–22 |
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 | 20–22 | |
TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 | 20–22 | |
TLS_DHE_DSS_WITH_DES_CBC_SHA | 1–8 | 1–8 |
TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA | 1–8 | 1–8 |
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA | 1–8 | 1–8 |
TLS_DHE_RSA_WITH_AES_128_CBC_SHA | 9+ | 9+ |
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 | 20+ | |
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 | 20+ | 20+ |
TLS_DHE_RSA_WITH_AES_256_CBC_SHA | 9+ | 20+ |
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 | 20+ | |
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 | 20+ | 20+ |
TLS_DHE_RSA_WITH_DES_CBC_SHA | 1–8 | 1–8 |
TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA | 1–8 | |
TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA | 1–8 | |
TLS_DH_DSS_WITH_DES_CBC_SHA | 1–8 | |
TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA | 1–8 | |
TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA | 1–8 | |
TLS_DH_RSA_WITH_DES_CBC_SHA | 1–8 | |
TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA | 1–8 | |
TLS_DH_anon_WITH_3DES_EDE_CBC_SHA | 1–8 | |
TLS_DH_anon_WITH_AES_128_CBC_SHA | 9–22 | |
TLS_DH_anon_WITH_AES_128_CBC_SHA256 | 20–22 | |
TLS_DH_anon_WITH_AES_128_GCM_SHA256 | 20–22 | |
TLS_DH_anon_WITH_AES_256_CBC_SHA | 9–22 | |
TLS_DH_anon_WITH_AES_256_CBC_SHA256 | 20–22 | |
TLS_DH_anon_WITH_AES_256_GCM_SHA384 | 20–22 | |
TLS_DH_anon_WITH_DES_CBC_SHA | 1–8 | |
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA | 20–22 | |
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA | 20+ | 20+ |
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | 20+ | |
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 | 20+ | 20+ |
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA | 20+ | 20+ |
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 | 20+ | |
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 | 20+ | 20+ |
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 | 24+ | 24+ |
TLS_ECDHE_ECDSA_WITH_NULL_SHA | 20–22 | |
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA | 20+ | 20–23 |
TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA | 21+ | 21+ |
TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA | 21+ | 21+ |
TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 | 24+ | 24+ |
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA | 20–22 | |
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA | 20+ | 20+ |
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 | 20+ | |
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 | 20+ | 20+ |
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA | 20+ | 20+ |
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 | 20+ | |
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 | 20+ | 20+ |
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 | 24+ | 24+ |
TLS_ECDHE_RSA_WITH_NULL_SHA | 20–22 | |
TLS_ECDHE_RSA_WITH_RC4_128_SHA | 20+ | 20–23 |
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA | 20–22 | |
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA | 20–22 | |
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 | 20–22 | |
TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 | 20–22 | |
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA | 20–22 | |
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 | 20–22 | |
TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 | 20–22 | |
TLS_ECDH_ECDSA_WITH_NULL_SHA | 20–22 | |
TLS_ECDH_ECDSA_WITH_RC4_128_SHA | 20–22 | |
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA | 20–22 | |
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA | 20–22 | |
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 | 20–22 | |
TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 | 20–22 | |
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA | 20–22 | |
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 | 20–22 | |
TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 | 20–22 | |
TLS_ECDH_RSA_WITH_NULL_SHA | 20–22 | |
TLS_ECDH_RSA_WITH_RC4_128_SHA | 20–22 | |
TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA | 20–22 | |
TLS_ECDH_anon_WITH_AES_128_CBC_SHA | 20–22 | |
TLS_ECDH_anon_WITH_AES_256_CBC_SHA | 20–22 | |
TLS_ECDH_anon_WITH_NULL_SHA | 20–22 | |
TLS_ECDH_anon_WITH_RC4_128_SHA | 20–22 | |
TLS_EMPTY_RENEGOTIATION_INFO_SCSV | 20+ | 20+ |
TLS_FALLBACK_SCSV | 21+ | |
TLS_NULL_WITH_NULL_NULL | 1–8 | |
TLS_PSK_WITH_3DES_EDE_CBC_SHA | 21–22 | |
TLS_PSK_WITH_AES_128_CBC_SHA | 21+ | 21+ |
TLS_PSK_WITH_AES_256_CBC_SHA | 21+ | 21+ |
TLS_PSK_WITH_RC4_128_SHA | 21+ | |
TLS_RSA_EXPORT_WITH_DES40_CBC_SHA | 1–8 | 1–8 |
TLS_RSA_WITH_3DES_EDE_CBC_SHA | 1–8 | 1–8 |
TLS_RSA_WITH_AES_128_CBC_SHA | 9+ | 9+ |
TLS_RSA_WITH_AES_128_CBC_SHA256 | 20+ | |
TLS_RSA_WITH_AES_128_GCM_SHA256 | 20+ | 20+ |
TLS_RSA_WITH_AES_256_CBC_SHA | 9+ | 20+ |
TLS_RSA_WITH_AES_256_CBC_SHA256 | 20+ | |
TLS_RSA_WITH_AES_256_GCM_SHA384 | 20+ | 20+ |
TLS_RSA_WITH_DES_CBC_SHA | 1–8 | 1–8 |
TLS_RSA_WITH_NULL_MD5 | 1–8 | |
TLS_RSA_WITH_NULL_SHA | 1–8 | |
TLS_RSA_WITH_NULL_SHA256 | 20–22 |
注 :PSK密码套件默认情况下只有在启用 SSLContext
通过创建该发动机已经初始化为 PSKKeyManager
。
Protected constructors |
|
---|---|
SSLEngine()
|
|
SSLEngine(String peerHost, int peerPort) 构造函数为 |
Public methods |
|
---|---|
abstract void |
beginHandshake() 在此SSLEngine上启动握手(初始或重新协商)。 |
abstract void |
closeInbound() 表示没有更多入站网络数据将发送到此 |
abstract void |
closeOutbound() 表示在此 |
abstract Runnable |
getDelegatedTask() 返回此 |
abstract boolean |
getEnableSessionCreation() 如果此引擎可能建立新的SSL会话,则返回true。 |
abstract String[] |
getEnabledCipherSuites() 返回当前启用在此引擎上使用的SSL密码套件的名称。 |
abstract String[] |
getEnabledProtocols() 返回当前启用的 |
SSLSession |
getHandshakeSession() 返回在SSL / TLS握手期间构造的 |
abstract SSLEngineResult.HandshakeStatus |
getHandshakeStatus() 返回此 |
abstract boolean |
getNeedClientAuth() 如果引擎 需要客户端身份验证,则返回true。 |
String |
getPeerHost() 返回对等体的主机名。 |
int |
getPeerPort() 返回对等体的端口号。 |
SSLParameters |
getSSLParameters() 返回对此SSLEngine有效的SSLParameters。 |
abstract SSLSession |
getSession() 返回此 |
abstract String[] |
getSupportedCipherSuites() 返回可用于此引擎的密码套件的名称。 |
abstract String[] |
getSupportedProtocols() 返回可用于此 |
abstract boolean |
getUseClientMode() 如果在握手时将引擎设置为使用客户端模式,则返回true。 |
abstract boolean |
getWantClientAuth() 如果引擎将 请求客户端身份验证,则返回true。 |
abstract boolean |
isInboundDone() 返回 |
abstract boolean |
isOutboundDone() 返回 |
abstract void |
setEnableSessionCreation(boolean flag) 控制是否可以通过此引擎建立新的SSL会话。 |
abstract void |
setEnabledCipherSuites(String[] suites) 设置启用在此引擎上使用的密码套件。 |
abstract void |
setEnabledProtocols(String[] protocols) 设置启用在此引擎上使用的协议版本。 |
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[] dsts) 尝试将SSL / TLS网络数据解码为一系列明文应用程序数据缓冲区。 |
SSLEngineResult |
unwrap(ByteBuffer src, ByteBuffer dst) 尝试将SSL / TLS网络数据解码为纯文本应用程序数据缓冲区。 |
abstract SSLEngineResult |
unwrap(ByteBuffer src, ByteBuffer[] dsts, int offset, int length) 尝试将SSL / TLS网络数据解码为纯文本应用程序数据缓冲区的子序列。 |
SSLEngineResult |
wrap(ByteBuffer[] srcs, ByteBuffer dst) 试图将明文字节从一系列数据缓冲区编码到SSL / TLS网络数据中。 |
SSLEngineResult |
wrap(ByteBuffer src, ByteBuffer dst) 尝试将明文应用程序数据的缓冲区编码到SSL / TLS网络数据中。 |
abstract SSLEngineResult |
wrap(ByteBuffer[] srcs, int offset, int length, ByteBuffer dst) 尝试将明文字节从数据缓冲区的子序列编码到SSL / TLS网络数据中。 |
Inherited methods |
|
---|---|
From class java.lang.Object
|
SSLEngine (String peerHost, int peerPort)
构造函数为 SSLEngine
。
SSLEngine
实现可以使用 peerHost
和 peerPort
参数作为其内部会话重用策略的提示。
某些密码套件(如Kerberos)需要远程主机名信息。 这个类的实现应该使用这个构造函数来使用Kerberos。
参数未由 SSLEngine
验证。
Parameters | |
---|---|
peerHost |
String : the name of the peer host |
peerPort |
int : the port number of the peer |
void beginHandshake ()
在此SSLEngine上启动握手(初始或重新协商)。
初始握手不需要此方法,因为如果握手尚未开始,则 wrap()
和 unwrap()
方法将隐式调用此方法。
请注意,对等方也可以通过发送适当的会话重新协商握手消息来请求与此 SSLEngine
进行会话重新协商。
与 SSLSocket#startHandshake()
方法不同,此方法在握手完成之前不会阻塞。
要强制完成SSL / TLS会话重新协商,在调用此方法之前,当前会话应该失效。
某些协议可能不支持现有引擎上的多次握手,并可能抛出 SSLException
。
Throws | |
---|---|
SSLException |
if a problem was encountered while signaling the SSLEngine to begin a new handshake. See the class description for more information on engine closure. |
IllegalStateException |
if the client/server mode has not yet been set. |
也可以看看:
void closeInbound ()
表示没有更多入站网络数据将发送到此 SSLEngine
。
如果应用程序通过调用closeOutbound()
启动关闭进程,则在某些情况下,启动程序不需要等待对等方的相应关闭消息。 (有关等待关闭警报的更多信息,请参阅TLS规范的第7.2.1节( RFC 2246 )。)在这种情况下,不需要调用此方法。
但是,如果应用程序未启动关闭过程,或者上述情况不适用,则应在每当SSL / TLS数据流结束时调用此方法。 这确保关闭入站端,并检查对端是否正确遵循SSL / TLS关闭过程,从而检测到可能的截断攻击。
这个方法是幂等的:如果入站端已经关闭,这个方法不会做任何事情。
应调用 wrap()
以刷新任何剩余的握手数据。
Throws | |
---|---|
SSLException |
if this engine has not received the proper SSL/TLS close notification message from the peer. |
也可以看看:
void closeOutbound ()
表示在此 SSLEngine
上不会再发送出站应用程序数据。
这个方法是幂等的:如果出站端已经关闭,这个方法不会做任何事情。
应该调用 wrap(ByteBuffer, ByteBuffer)
来刷新任何剩余的握手数据。
也可以看看:
Runnable getDelegatedTask ()
返回此 SSLEngine
的委托 Runnable
任务。
SSLEngine
操作可能需要SSLEngine
操作的结果,或可能需要很长时间才能完成。 此方法用于获取未完成的Runnable
操作(任务)。 每个任务必须分配一个线程(可能是当前的)来执行run
操作。 一旦run
方法返回, Runnable
对象不再需要,可能会被丢弃。
创建此对象时,委派的任务将在 AccessControlContext
中运行。
对此方法的调用将每个返回的任务完全返回一次。
可以并行运行多个委托任务。
Returns | |
---|---|
Runnable |
a delegated Runnable task, or null if none are available. |
boolean getEnableSessionCreation ()
如果此引擎可能建立新的SSL会话,则返回true。
Returns | |
---|---|
boolean |
true indicates that sessions may be created; this is the default. false indicates that an existing session must be resumed |
String[] getEnabledCipherSuites ()
返回当前启用在此引擎上使用的SSL密码套件的名称。 当第一次创建SSLEngine时,所有启用的密码套件都支持最低的服务质量。 因此,在某些环境中,这个值可能是空的。
即使套件已启用,它也可能永远不会被使用。 (例如,对等方不支持它,套件的必需证书/私钥不可用,或启用匿名套件但需要验证。)
Returns | |
---|---|
String[] |
an array of cipher suite names |
String[] getEnabledProtocols ()
返回当前启用的 SSLEngine
协议版本的名称。
Returns | |
---|---|
String[] |
an array of protocols |
SSLSession getHandshakeSession ()
返回在SSL / TLS握手期间构造的 SSLSession
。
TLS协议可能会协商使用此类的实例时需要的参数,但在SSLSession
已完全初始化并通过getSession
可用之前,TLS协议可能会协商这些参数。 例如,有效签名算法列表可能会限制TrustManager决策期间可以使用的证书的类型,或者可以调整最大TLS分段大小的大小以更好地支持网络环境。
这种方法提供了对正在构建的SSLSession
早期访问。 根据握手的进展程度,有些数据可能尚未可用。 例如,如果远程服务器将发送一个证书链,但链尚未没有被处理,则getPeerCertificates
的方法SSLSession
将抛出SSLPeerUnverifiedException。 一旦该链已经被处理, getPeerCertificates
将返回适当的值。
Returns | |
---|---|
SSLSession |
null if this instance is not currently handshaking, or if the current handshake has not progressed far enough to create a basic SSLSession. Otherwise, this method returns the SSLSession currently being negotiated. |
Throws | |
---|---|
UnsupportedOperationException |
if the underlying provider does not implement the operation. |
SSLEngineResult.HandshakeStatus getHandshakeStatus ()
返回此 SSLEngine
的当前握手状态。
Returns | |
---|---|
SSLEngineResult.HandshakeStatus |
the current SSLEngineResult.HandshakeStatus . |
boolean getNeedClientAuth ()
如果引擎需要客户端身份验证,则返回true。 该选项仅对服务器模式下的引擎有用。
Returns | |
---|---|
boolean |
true if client authentication is required, or false if no client authentication is desired. |
String getPeerHost ()
返回对等体的主机名。
请注意,该值未经过身份验证,因此不应被依赖。
Returns | |
---|---|
String |
the host name of the peer, or null if nothing is available. |
int getPeerPort ()
返回对等体的端口号。
请注意,该值未经过身份验证,因此不应被依赖。
Returns | |
---|---|
int |
the port number of the peer, or -1 if nothing is available. |
SSLParameters getSSLParameters ()
返回对此SSLEngine有效的SSLParameters。 返回的SSLParameters的密码组和协议始终为非空值。
Returns | |
---|---|
SSLParameters |
the SSLParameters in effect for this SSLEngine. |
SSLSession getSession ()
返回 SSLSession
中使用的 SSLEngine
。
这些可以长期存在,并且经常对应于某个用户的整个登录会话。 会话指定了一个特定的密码套件,该套件正被该会话中的所有连接以及会话客户端和服务器的身份标识所使用。
与 getSession()
不同,此方法在握手完成之前不会阻塞。
在初始握手完成之前,此方法返回一个会话对象,报告“SSL_NULL_WITH_NULL_NULL”的无效密码套件。
Returns | |
---|---|
SSLSession |
the SSLSession for this SSLEngine |
也可以看看:
String[] getSupportedCipherSuites ()
返回可用于此引擎的密码套件的名称。 通常,默认情况下,只有这些列表中的一部分会实际启用,因为此列表可能包含不符合服务质量要求的密码套件。 这种密码套件在专门的应用程序中可能很有用。
Returns | |
---|---|
String[] |
an array of cipher suite names |
String[] getSupportedProtocols ()
返回可用于此 SSLEngine
的协议的名称。
Returns | |
---|---|
String[] |
an array of protocols supported |
boolean getUseClientMode ()
如果在握手时将引擎设置为使用客户端模式,则返回true。
Returns | |
---|---|
boolean |
true if the engine should do handshaking in "client" mode |
也可以看看:
boolean getWantClientAuth ()
如果引擎将请求客户端身份验证,则返回true。 该选项仅适用于服务器模式下的引擎。
Returns | |
---|---|
boolean |
true if client authentication is requested, or false if no client authentication is desired. |
boolean isInboundDone ()
返回 unwrap(ByteBuffer, ByteBuffer)
是否将接受任何更多入站数据消息。
Returns | |
---|---|
boolean |
true if the SSLEngine will not consume anymore network data (and by implication, will not produce any more application data.) |
也可以看看:
boolean isOutboundDone ()
返回 wrap(ByteBuffer, ByteBuffer)
是否会产生更多出站数据消息。
请注意,在关闭阶段, SSLEngine
可能会生成必须发送给对等方的握手关闭数据。 必须调用wrap()
才能生成此数据。 当此方法返回true时,不会再创建出站数据。
Returns | |
---|---|
boolean |
true if the SSLEngine will not produce any more network data |
也可以看看:
void setEnableSessionCreation (boolean flag)
控制是否可以通过此引擎建立新的SSL会话。 如果会话创建不被允许,并且没有现有的会话可以恢复,那么将不会有成功的握手。
Parameters | |
---|---|
flag |
boolean : true indicates that sessions may be created; this is the default. false indicates that an existing session must be resumed |
也可以看看:
void setEnabledCipherSuites (String[] suites)
设置启用在此引擎上使用的密码套件。
suites
参数中的每个密码套件必须已由getSupportedCipherSuites()列出,否则该方法将失败。 成功调用此方法后,仅启用suites
参数中列出的套件以供使用。
有关更多信息,请参阅 getEnabledCipherSuites()
以了解特定密码套件可能永远不会在引擎上使用的原因。
Parameters | |
---|---|
suites |
String : Names of all the cipher suites to enable |
Throws | |
---|---|
IllegalArgumentException |
when one or more of the ciphers named by the parameter is not supported, or when the parameter is null. |
void setEnabledProtocols (String[] protocols)
设置启用在此引擎上使用的协议版本。
该协议必须已被getSupportedProtocols()列为受支持。 成功调用此方法后,只有protocols
参数中列出的协议才能使用。
Parameters | |
---|---|
protocols |
String : Names of all the protocols to enable. |
Throws | |
---|---|
IllegalArgumentException |
when one or more of the protocols named by the parameter is not supported or when the protocols parameter is null. |
也可以看看:
void setNeedClientAuth (boolean need)
配置引擎以要求客户端身份验证。 该选项仅适用于服务器模式下的引擎。
引擎的客户端身份验证设置为以下之一:
与 setWantClientAuth(boolean)
不同,如果设置此选项并且客户端选择不提供有关其自身的身份验证信息, 则协商将停止,并且引擎将开始其关闭过程 。
调用此方法将覆盖此方法或 setWantClientAuth(boolean)
所做的任何以前的设置。
Parameters | |
---|---|
need |
boolean : set to true if client authentication is required, or false if no client authentication is desired. |
void setSSLParameters (SSLParameters params)
将SSLParameters应用于此引擎。
意即:
params.getCipherSuites()
is non-null, setEnabledCipherSuites()
is called with that value params.getProtocols()
is non-null, setEnabledProtocols()
is called with that value params.getNeedClientAuth()
or params.getWantClientAuth()
return true
, setNeedClientAuth(true)
and setWantClientAuth(true)
are called, respectively; otherwise setWantClientAuth(false)
is called. Parameters | |
---|---|
params |
SSLParameters : the parameters |
Throws | |
---|---|
IllegalArgumentException |
if the setEnabledCipherSuites() or the setEnabledProtocols() call fails |
void setUseClientMode (boolean mode)
握手时将引擎配置为使用客户端(或服务器)模式。
必须在发生任何握手之前调用此方法。 一旦握手开始,该模式无法在该引擎的使用期限内重置。
服务器通常会对自己进行身份验证,并且客户端不需要这样做。
Parameters | |
---|---|
mode |
boolean : true if the engine should start its handshaking in "client" mode |
Throws | |
---|---|
IllegalArgumentException |
if a mode change is attempted after the initial handshake has begun. |
也可以看看:
void setWantClientAuth (boolean want)
配置引擎以请求客户端身份验证。 该选项仅适用于服务器模式下的引擎。
引擎的客户端身份验证设置为以下之一:
与 setNeedClientAuth(boolean)
不同,如果设置了此选项并且客户端选择不提供有关其自身的身份验证信息, 则谈判将继续 。
调用此方法会覆盖此方法或 setNeedClientAuth(boolean)
所做的任何以前的设置。
Parameters | |
---|---|
want |
boolean : set to true if client authentication is requested, or false if no client authentication is desired. |
SSLEngineResult unwrap (ByteBuffer src, ByteBuffer[] dsts)
尝试将SSL / TLS网络数据解码为一系列明文应用程序数据缓冲区。
此方法的调用的行为与调用完全相同:
engine.unwrap(src, dsts, 0, dsts.length);
Parameters src
ByteBuffer
: aByteBuffer
containing inbound network data.dsts
ByteBuffer
: an array ofByteBuffer
s to hold inbound application data.
Returns SSLEngineResult
an SSLEngineResult
describing the result of this operation.
Throws SSLException
A problem was encountered while processing the data that caused the SSLEngine
to abort. See the class description for more information on engine closure.ReadOnlyBufferException
if any of the dst
buffers are read-only.IllegalArgumentException
if either src
ordsts
is null, or if any element indsts
is null.IllegalStateException
if the client/server mode has not yet been set.
SSLEngineResult unwrap (ByteBuffer src, ByteBuffer dst)
尝试将SSL / TLS网络数据解码为纯文本应用程序数据缓冲区。
此方法的调用的行为与调用完全相同:
engine.unwrap(src, new ByteBuffer [] { dst }, 0, 1);
Parameters src
ByteBuffer
: aByteBuffer
containing inbound network data.dst
ByteBuffer
: aByteBuffer
to hold inbound application data.
Returns SSLEngineResult
an SSLEngineResult
describing the result of this operation.
Throws SSLException
A problem was encountered while processing the data that caused the SSLEngine
to abort. See the class description for more information on engine closure.ReadOnlyBufferException
if the dst
buffer is read-only.IllegalArgumentException
if either src
ordst
is null.IllegalStateException
if the client/server mode has not yet been set.
SSLEngineResult unwrap (ByteBuffer src, ByteBuffer[] dsts, int offset, int length)
尝试将SSL / TLS网络数据解码为纯文本应用程序数据缓冲区的子序列。 这种“散布”操作在单次调用中将一系列字节解码为一个或多个给定的缓冲区序列。 在实现网络协议或文件格式时,散布解包通常很有用,例如,将数据分组为包含一个或多个固定长度头部和随后可变长度主体的段。 见ScatteringByteChannel
关于分散的更多信息,并read(ByteBuffer[], int, int)
对序列行为的更多信息。
根据SSLEngine的状态,此方法可能会消耗网络数据而不产生任何应用程序数据(例如,它可能会消耗握手数据)。
该应用程序负责可靠地从对等方获取网络数据,并负责按收到的顺序调用对数据的解包()。 应用程序必须正确地将多个调用同步到此方法。
如果这个 SSLEngine
尚未开始其初始握手,则此方法将自动开始握手。
此方法将尝试使用一个完整的SSL / TLS网络数据包,但永远不会消耗超过缓冲区中剩余字节的总和。 更新每个ByteBuffer
的位置以反映消耗或生成的数据量。 限制保持不变。
src
和 dsts ByteBuffer
所使用的基础内存不能相同。
由于此调用,入站网络缓冲区可能会被修改:因此,如果网络数据包被用于某些次要目的,则在调用此方法之前应重复数据。 注意:网络数据不会对第二个SSLEngine有用,因为每个SSLEngine都包含影响SSL / TLS消息的唯一随机状态。
有关引擎关闭的更多信息,请参阅类描述。
Parameters | |
---|---|
src |
ByteBuffer : a ByteBuffer containing inbound network data. |
dsts |
ByteBuffer : an array of ByteBuffer s to hold inbound application data. |
offset |
int : The offset within the buffer array of the first buffer from which bytes are to be transferred; it must be non-negative and no larger than dsts.length . |
length |
int : The maximum number of buffers to be accessed; it must be non-negative and no larger than dsts.length - offset . |
Returns | |
---|---|
SSLEngineResult |
an SSLEngineResult describing the result of this operation. |
Throws | |
---|---|
SSLException |
A problem was encountered while processing the data that caused the SSLEngine to abort. See the class description for more information on engine closure. |
IndexOutOfBoundsException |
If the preconditions on the offset and length parameters do not hold. |
ReadOnlyBufferException |
if any of the dst buffers are read-only. |
IllegalArgumentException |
if either src or dsts is null, or if any element in the dsts subsequence specified is null. |
IllegalStateException |
if the client/server mode has not yet been set. |
SSLEngineResult wrap (ByteBuffer[] srcs, ByteBuffer dst)
试图将明文字节从一系列数据缓冲区编码到SSL / TLS网络数据中。
此方法的调用的行为与调用完全相同:
engine.wrap(srcs, 0, srcs.length, dst);
Parameters srcs
ByteBuffer
: an array ofByteBuffers
containing the outbound application datadst
ByteBuffer
: aByteBuffer
to hold outbound network data
Returns SSLEngineResult
an SSLEngineResult
describing the result of this operation.
Throws SSLException
A problem was encountered while processing the data that caused the SSLEngine
to abort. See the class description for more information on engine closure.ReadOnlyBufferException
if the dst
buffer is read-only.IllegalArgumentException
if either srcs
ordst
is null, or if any element insrcs
is null.IllegalStateException
if the client/server mode has not yet been set.
SSLEngineResult wrap (ByteBuffer src, ByteBuffer dst)
尝试将明文应用程序数据的缓冲区编码到SSL / TLS网络数据中。
此方法的调用的行为与调用完全相同:
engine.wrap(new ByteBuffer [] { src }, 0, 1, dst);
Parameters src
ByteBuffer
: aByteBuffer
containing outbound application datadst
ByteBuffer
: aByteBuffer
to hold outbound network data
Returns SSLEngineResult
an SSLEngineResult
describing the result of this operation.
Throws SSLException
A problem was encountered while processing the data that caused the SSLEngine
to abort. See the class description for more information on engine closure.ReadOnlyBufferException
if the dst
buffer is read-only.IllegalArgumentException
if either src
ordst
is null.IllegalStateException
if the client/server mode has not yet been set.
SSLEngineResult wrap (ByteBuffer[] srcs, int offset, int length, ByteBuffer dst)
尝试将明文字节从数据缓冲区的子序列编码到SSL / TLS网络数据中。 这种“收集”操作在单次调用中对来自一个或多个给定序列的缓冲器的一系列字节进行编码。 在实现网络协议或文件格式时,收集包裹通常很有用,例如,将数据分组为包含一个或多个固定长度标头,后跟可变长度主体的段。 见GatheringByteChannel
有关收集更多信息,并write(ByteBuffer[], int, int)
对序列行为的更多信息。
根据SSLEngine的状态,此方法可能会生成网络数据而不消耗任何应用程序数据(例如,它可能会生成握手数据)。
应用程序负责可靠地将网络数据传输到对等体,并确保通过多次调用wrap()所创建的数据按照生成它的相同顺序传输。 应用程序必须正确地将多个调用同步到此方法。
如果这个 SSLEngine
尚未开始其初始握手,则此方法将自动开始握手。
此方法将尝试生成一个SSL / TLS数据包,并将尽可能多地使用源数据,但永远不会消耗超过每个缓冲区中剩余字节的总和。 更新每个ByteBuffer
的位置以反映消耗或生成的数据量。 限制保持不变。
srcs
和 dst ByteBuffer
所使用的基本内存不能相同。
有关引擎关闭的更多信息,请参阅类描述。
Parameters | |
---|---|
srcs |
ByteBuffer : an array of ByteBuffers containing the outbound application data |
offset |
int : The offset within the buffer array of the first buffer from which bytes are to be retrieved; it must be non-negative and no larger than srcs.length |
length |
int : The maximum number of buffers to be accessed; it must be non-negative and no larger than srcs.length - offset |
dst |
ByteBuffer : a ByteBuffer to hold outbound network data |
Returns | |
---|---|
SSLEngineResult |
an SSLEngineResult describing the result of this operation. |
Throws | |
---|---|
SSLException |
A problem was encountered while processing the data that caused the SSLEngine to abort. See the class description for more information on engine closure. |
IndexOutOfBoundsException |
if the preconditions on the offset and length parameters do not hold. |
ReadOnlyBufferException |
if the dst buffer is read-only. |
IllegalArgumentException |
if either srcs or dst is null, or if any element in the srcs subsequence specified is null. |
IllegalStateException |
if the client/server mode has not yet been set. |