Most visited

Recently visited

Added in API level 1

SSLEngine

public abstract class SSLEngine
extends Object

java.lang.Object
   ↳ javax.net.ssl.SSLEngine


一种使用协议(如安全套接字层(SSL)或 IETF RFC 2246 "Transport Layer Security" (TLS)协议)实现安全通信的类,但是与传输无关。

安全通信模式包括:

These kinds of protection are specified by a "cipher suite", which is a combination of cryptographic algorithms used by a given SSL connection. During the negotiation process, the two endpoints must agree on a cipher suite that is available in both environments. If there is no such suite in common, no SSL connection can be established, and no data can be exchanged.

所使用的密码套件由称为“握手”的协商过程建立。 此过程的目标是创建或重新加入“会话”,这可以保护许多连接随着时间的推移。 握手完成后,您可以使用getSession()方法访问会话属性。

SSLSocket类提供了大部分相同的安全功能,但所有入站和出站数据都使用底层Socket自动传输,该设计使用了阻塞模型。 虽然这适用于许多应用程序,但该模型不能提供大型服务器所需的可扩展性。

SSLEngine的主要区别在于它在入站和出站字节流上运行,与传输机制无关。 SSLEngine用户有责任为对等SSLEngine安排可靠的I / O传输。 通过从I / O传输机制中分离出SSL / TLS抽象,所述SSLEngine可用于各种各样的I / O类型的,例如non-blocking I/O (polling)selectable non-blocking I/OSocket与传统的输入/ OutputStreams,本地ByteBuffers或字节数组, future asynchronous I/O models等等。

在较高的水平上, SSLEngine因此出现:

                   app data

                |           ^
                |     |     |
                v     |     |
           +----+-----|-----+----+
           |          |          |
           |       SSL|Engine    |
   wrap()  |          |          |  unwrap()
           | OUTBOUND | INBOUND  |
           |          |          |
           +----+-----|-----+----+
                |     |     ^
                |     |     |
                v           |

                   net data
 
Application 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有五个不同的阶段。

  1. Creation - The 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.
  2. Initial Handshake - The initial handshake is a procedure by which the two peers exchange communication parameters until an SSLSession is established. Application data can not be sent during this phase.
  3. Application Data - Once the communication parameters have been established and the handshake is complete, application data may flow through the SSLEngine. Outbound application messages are encrypted and integrity protected, and inbound messages reverse the process.
  4. Rehandshaking - Either side may request a renegotiation of the session at any time during the Application Data phase. New handshaking data can be intermixed among the application data. Before starting the rehandshake phase, the application may reset the SSL/TLS communication parameters such as the list of enabled ciphersuites and whether to use client authentication, but can not change between client/server modes. As before, once handshaking has begun, any new SSLEngine configuration settings will not be used until the next handshake.
  5. Closure - When the connection is no longer needed, the application should close the 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.
An 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()用于向引擎发信号表示应用程序不会再发送任何数据。

对等体将通过发送自己的闭包握手消息来表明其关闭的意图。 此消息已被接收和处理的地方后SSLEngineunwrap()调用,应用程序可以检测关闭,通过调用unwrap()并寻找SSLEngineResult状态为‘关闭’,或者如果isInboundDone()返回true。 如果由于某种原因,对端关闭通信链路而没有发送正确的SSL / TLS关闭消息,则应用程序可以检测到流结束,并且可以通过closeInbound()向引擎发送没有更多入站消息要处理的信号。 某些应用程序可能会选择要求从对等方有序关闭消息,在这种情况下,他们可以检查闭包是由握手消息生成的,而不是由流结束条件生成的。

有两组密码套件,您在管理密码套件时需要了解这些套件:

Implementation defaults require that only cipher suites which authenticate servers and provide confidentiality be enabled by default. Only if both sides explicitly agree to unauthenticated and/or non-private (unencrypted) communications will such a cipher suite be selected.

每个SSL / TLS连接必须有一个客户端和一个服务器,因此每个端点必须决定承担哪个角色。 这种选择决定了谁开始握手过程以及每个参与方应该发送哪种类型的消息。 方法setUseClientMode(boolean)配置模式。 一旦初始握手开始,即使在执行重新协商时, SSLEngine也不能在客户端和服务器模式之间切换。

应用程序可能会选择在不同线程中处理委派的任务。 当创建SSLEngine ,当前的AccessControlContext被保存。 所有未来的委托任务都将使用此上下文进行处理:也就是说,所有访问控制决策都将使用在引擎创建时捕获的上下文进行。


Concurrency Notes: There are two concurrency issues to be aware of:
  1. The wrap() and unwrap() methods may execute concurrently of each other.
  2. The SSL/TLS protocols employ ordered packets. Applications must take care to ensure that generated packets are delivered in sequence. If packets arrive out-of-order, unexpected or fatal results may occur.

    例如:

                  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.

Default configuration for different Android versions

从默认 SSLContext获得的 SSLEngine实例配置如下:

Protocols

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 suites

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

也可以看看:

Summary

Protected constructors

SSLEngine()

SSLEngine构造函数不提供内部会话重用策略的提示。

SSLEngine(String peerHost, int peerPort)

构造函数为 SSLEngine

Public methods

abstract void beginHandshake()

在此SSLEngine上启动握手(初始或重新协商)。

abstract void closeInbound()

表示没有更多入站网络数据将发送到此 SSLEngine

abstract void closeOutbound()

表示在此 SSLEngine上不会再发送出站应用程序数据。

abstract Runnable getDelegatedTask()

返回此 SSLEngine的委托 Runnable任务。

abstract boolean getEnableSessionCreation()

如果此引擎可能建立新的SSL会话,则返回true。

abstract String[] getEnabledCipherSuites()

返回当前启用在此引擎上使用的SSL密码套件的名称。

abstract String[] getEnabledProtocols()

返回当前启用的 SSLEngine协议版本的名称。

SSLSession getHandshakeSession()

返回在SSL / TLS握手期间构造的 SSLSession

abstract SSLEngineResult.HandshakeStatus getHandshakeStatus()

返回此 SSLEngine的当前握手状态。

abstract boolean getNeedClientAuth()

如果引擎 需要客户端身份验证,则返回true。

String getPeerHost()

返回对等体的主机名。

int getPeerPort()

返回对等体的端口号。

SSLParameters getSSLParameters()

返回对此SSLEngine有效的SSLParameters。

abstract SSLSession getSession()

返回此 SSLSession正在使用的 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 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

Protected constructors

SSLEngine

Added in API level 1
SSLEngine ()

SSLEngine构造函数不提供内部会话重用策略的提示。

也可以看看:

SSLEngine

Added in API level 1
SSLEngine (String peerHost, 
                int peerPort)

构造函数为 SSLEngine

SSLEngine实现可以使用 peerHostpeerPort参数作为其内部会话重用策略的提示。

某些密码套件(如Kerberos)需要远程主机名信息。 这个类的实现应该使用这个构造函数来使用Kerberos。

参数未由 SSLEngine验证。

Parameters
peerHost String: the name of the peer host
peerPort int: the port number of the peer

也可以看看:

Public methods

beginHandshake

Added in API level 1
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.

也可以看看:

closeInbound

Added in API level 1
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.

也可以看看:

closeOutbound

Added in API level 1
void closeOutbound ()

表示在此 SSLEngine上不会再发送出站应用程序数据。

这个方法是幂等的:如果出站端已经关闭,这个方法不会做任何事情。

应该调用 wrap(ByteBuffer, ByteBuffer)来刷新任何剩余的握手数据。

也可以看看:

getDelegatedTask

Added in API level 1
Runnable getDelegatedTask ()

返回此 SSLEngine的委托 Runnable任务。

SSLEngine操作可能需要SSLEngine操作的结果,或可能需要很长时间才能完成。 此方法用于获取未完成的Runnable操作(任务)。 每个任务必须分配一个线程(可能是当前的)来执行run操作。 一旦run方法返回, Runnable对象不再需要,可能会被丢弃。

创建此对象时,委派的任务将在 AccessControlContext中运行。

对此方法的调用将每个返回的任务完全返回一次。

可以并行运行多个委托任务。

Returns
Runnable a delegated Runnable task, or null if none are available.

getEnableSessionCreation

Added in API level 1
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

也可以看看:

getEnabledCipherSuites

Added in API level 1
String[] getEnabledCipherSuites ()

返回当前启用在此引擎上使用的SSL密码套件的名称。 当第一次创建SSLEngine时,所有启用的密码套件都支持最低的服务质量。 因此,在某些环境中,这个值可能是空的。

即使套件已启用,它也可能永远不会被使用。 (例如,对等方不支持它,套件的必需证书/私钥不可用,或启用匿名套件但需要验证。)

Returns
String[] an array of cipher suite names

也可以看看:

getEnabledProtocols

Added in API level 1
String[] getEnabledProtocols ()

返回当前启用的 SSLEngine协议版本的名称。

Returns
String[] an array of protocols

也可以看看:

getHandshakeSession

Added in API level 24
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.

也可以看看:

getHandshakeStatus

Added in API level 1
SSLEngineResult.HandshakeStatus getHandshakeStatus ()

返回此 SSLEngine的当前握手状态。

Returns
SSLEngineResult.HandshakeStatus the current SSLEngineResult.HandshakeStatus.

getNeedClientAuth

Added in API level 1
boolean getNeedClientAuth ()

如果引擎需要客户端身份验证,则返回true。 该选项仅对服务器模式下的引擎有用。

Returns
boolean true if client authentication is required, or false if no client authentication is desired.

也可以看看:

getPeerHost

Added in API level 1
String getPeerHost ()

返回对等体的主机名。

请注意,该值未经过身份验证,因此不应被依赖。

Returns
String the host name of the peer, or null if nothing is available.

getPeerPort

Added in API level 1
int getPeerPort ()

返回对等体的端口号。

请注意,该值未经过身份验证,因此不应被依赖。

Returns
int the port number of the peer, or -1 if nothing is available.

getSSLParameters

Added in API level 9
SSLParameters getSSLParameters ()

返回对此SSLEngine有效的SSLParameters。 返回的SSLParameters的密码组和协议始终为非空值。

Returns
SSLParameters the SSLParameters in effect for this SSLEngine.

getSession

Added in API level 1
SSLSession getSession ()

返回 SSLSession中使用的 SSLEngine

这些可以长期存在,并且经常对应于某个用户的整个登录会话。 会话指定了一个特定的密码套件,该套件正被该会话中的所有连接以及会话客户端和服务器的身份标识所使用。

getSession()不同,此方法在握手完成之前不会阻塞。

在初始握手完成之前,此方法返回一个会话对象,报告“SSL_NULL_WITH_NULL_NULL”的无效密码套件。

Returns
SSLSession the SSLSession for this SSLEngine

也可以看看:

getSupportedCipherSuites

Added in API level 1
String[] getSupportedCipherSuites ()

返回可用于此引擎的密码套件的名称。 通常,默认情况下,只有这些列表中的一部分会实际启用,因为此列表可能包含不符合服务质量要求的密码套件。 这种密码套件在专门的应用程序中可能很有用。

Returns
String[] an array of cipher suite names

也可以看看:

getSupportedProtocols

Added in API level 1
String[] getSupportedProtocols ()

返回可用于此 SSLEngine的协议的名称。

Returns
String[] an array of protocols supported

getUseClientMode

Added in API level 1
boolean getUseClientMode ()

如果在握手时将引擎设置为使用客户端模式,则返回true。

Returns
boolean true if the engine should do handshaking in "client" mode

也可以看看:

getWantClientAuth

Added in API level 1
boolean getWantClientAuth ()

如果引擎将请求客户端身份验证,则返回true。 该选项仅适用于服务器模式下的引擎。

Returns
boolean true if client authentication is requested, or false if no client authentication is desired.

也可以看看:

isInboundDone

Added in API level 1
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.)

也可以看看:

isOutboundDone

Added in API level 1
boolean isOutboundDone ()

返回 wrap(ByteBuffer, ByteBuffer)是否会产生更多出站数据消息。

请注意,在关闭阶段, SSLEngine可能会生成必须发送给对等方的握手关闭数据。 必须调用wrap()才能生成此数据。 当此方法返回true时,不会再创建出站数据。

Returns
boolean true if the SSLEngine will not produce any more network data

也可以看看:

setEnableSessionCreation

Added in API level 1
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

也可以看看:

setEnabledCipherSuites

Added in API level 1
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.

也可以看看:

setEnabledProtocols

Added in API level 1
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.

也可以看看:

setNeedClientAuth

Added in API level 1
void setNeedClientAuth (boolean need)

配置引擎以要求客户端身份验证。 该选项仅适用于服务器模式下的引擎。

引擎的客户端身份验证设置为以下之一:

  • client authentication required
  • client authentication requested
  • no client authentication desired

setWantClientAuth(boolean)不同,如果设置此选项并且客户端选择不提供有关其自身的身份验证信息, 则协商将停止,并且引擎将开始其关闭过程

调用此方法将覆盖此方法或 setWantClientAuth(boolean)所做的任何以前的设置。

Parameters
need boolean: set to true if client authentication is required, or false if no client authentication is desired.

也可以看看:

setSSLParameters

Added in API level 9
void setSSLParameters (SSLParameters params)

将SSLParameters应用于此引擎。

意即:

  • if params.getCipherSuites() is non-null, setEnabledCipherSuites() is called with that value
  • if params.getProtocols() is non-null, setEnabledProtocols() is called with that value
  • if 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

setUseClientMode

Added in API level 1
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.

也可以看看:

setWantClientAuth

Added in API level 1
void setWantClientAuth (boolean want)

配置引擎以请求客户端身份验证。 该选项仅适用于服务器模式下的引擎。

引擎的客户端身份验证设置为以下之一:

  • client authentication required
  • client authentication requested
  • no client authentication desired

setNeedClientAuth(boolean)不同,如果设置了此选项并且客户端选择不提供有关其自身的身份验证信息, 则谈判将继续

调用此方法会覆盖此方法或 setNeedClientAuth(boolean)所做的任何以前的设置。

Parameters
want boolean: set to true if client authentication is requested, or false if no client authentication is desired.

也可以看看:

unwrap

Added in API level 1
SSLEngineResult unwrap (ByteBuffer src, 
                ByteBuffer[] dsts)

尝试将SSL / TLS网络数据解码为一系列明文应用程序数据缓冲区。

此方法的调用的行为与调用完全相同:

 engine.unwrap(src, dsts, 0, dsts.length);
 

Parameters
src ByteBuffer: a ByteBuffer containing inbound network data.
dsts ByteBuffer: an array of ByteBuffers 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 or dsts is null, or if any element in dsts is null.
IllegalStateException if the client/server mode has not yet been set.

unwrap

Added in API level 1
SSLEngineResult unwrap (ByteBuffer src, 
                ByteBuffer dst)

尝试将SSL / TLS网络数据解码为纯文本应用程序数据缓冲区。

此方法的调用的行为与调用完全相同:

 engine.unwrap(src, new ByteBuffer [] { dst }, 0, 1);
 

Parameters
src ByteBuffer: a ByteBuffer containing inbound network data.
dst ByteBuffer: a ByteBuffer 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 or dst is null.
IllegalStateException if the client/server mode has not yet been set.

unwrap

Added in API level 1
SSLEngineResult unwrap (ByteBuffer src, 
                ByteBuffer[] dsts, 
                int offset, 
                int length)

尝试将SSL / TLS网络数据解码为纯文本应用程序数据缓冲区的子序列。 这种“散布”操作在单次调用中将一系列字节解码为一个或多个给定的缓冲区序列。 在实现网络协议或文件格式时,散布解包通常很有用,例如,将数据分组为包含一个或多个固定长度头部和随后可变长度主体的段。 ScatteringByteChannel关于分散的更多信息,并read(ByteBuffer[], int, int)对序列行为的更多信息。

根据SSLEngine的状态,此方法可能会消耗网络数据而不产生任何应用程序数据(例如,它可能会消耗握手数据)。

该应用程序负责可靠地从对等方获取网络数据,并负责按收到的顺序调用对数据的解包()。 应用程序必须正确地将多个调用同步到此方法。

如果这个 SSLEngine尚未开始其初始握手,则此方法将自动开始握手。

此方法将尝试使用一个完整的SSL / TLS网络数据包,但永远不会消耗超过缓冲区中剩余字节的总和。 更新每个ByteBuffer的位置以反映消耗或生成的数据量。 限制保持不变。

srcdsts ByteBuffer所使用的基础内存不能相同。

由于此调用,入站网络缓冲区可能会被修改:因此,如果网络数据包被用于某些次要目的,则在调用此方法之前应重复数据。 注意:网络数据不会对第二个SSLEngine有用,因为每个SSLEngine都包含影响SSL / TLS消息的唯一随机状态。

有关引擎关闭的更多信息,请参阅类描述。

Parameters
src ByteBuffer: a ByteBuffer containing inbound network data.
dsts ByteBuffer: an array of ByteBuffers 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.

也可以看看:

wrap

Added in API level 1
SSLEngineResult wrap (ByteBuffer[] srcs, 
                ByteBuffer dst)

试图将明文字节从一系列数据缓冲区编码到SSL / TLS网络数据中。

此方法的调用的行为与调用完全相同:

 engine.wrap(srcs, 0, srcs.length, dst);
 

Parameters
srcs ByteBuffer: an array of ByteBuffers containing the outbound application data
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.
ReadOnlyBufferException if the dst buffer is read-only.
IllegalArgumentException if either srcs or dst is null, or if any element in srcs is null.
IllegalStateException if the client/server mode has not yet been set.

wrap

Added in API level 1
SSLEngineResult wrap (ByteBuffer src, 
                ByteBuffer dst)

尝试将明文应用程序数据的缓冲区编码到SSL / TLS网络数据中。

此方法的调用的行为与调用完全相同:

 engine.wrap(new ByteBuffer [] { src }, 0, 1, dst);
 

Parameters
src ByteBuffer: a ByteBuffer containing outbound application data
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.
ReadOnlyBufferException if the dst buffer is read-only.
IllegalArgumentException if either src or dst is null.
IllegalStateException if the client/server mode has not yet been set.

wrap

Added in API level 1
SSLEngineResult wrap (ByteBuffer[] srcs, 
                int offset, 
                int length, 
                ByteBuffer dst)

尝试将明文字节从数据缓冲区的子序列编码到SSL / TLS网络数据中。 这种“收集”操作在单次调用中对来自一个或多个给定序列的缓冲器的一系列字节进行编码。 在实现网络协议或文件格式时,收集包裹通常很有用,例如,将数据分组为包含一个或多个固定长度标头,后跟可变长度主体的段。 GatheringByteChannel有关收集更多信息,并write(ByteBuffer[], int, int)对序列行为的更多信息。

根据SSLEngine的状态,此方法可能会生成网络数据而不消耗任何应用程序数据(例如,它可能会生成握手数据)。

应用程序负责可靠地将网络数据传输到对等体,并确保通过多次调用wrap()所创建的数据按照生成它的相同顺序传输。 应用程序必须正确地将多个调用同步到此方法。

如果这个 SSLEngine尚未开始其初始握手,则此方法将自动开始握手。

此方法将尝试生成一个SSL / TLS数据包,并将尽可能多地使用源数据,但永远不会消耗超过每个缓冲区中剩余字节的总和。 更新每个ByteBuffer的位置以反映消耗或生成的数据量。 限制保持不变。

srcsdst 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.

也可以看看:

Hooray!