SSL/TLS 支持

支持安全套接字层/传输层安全协议。使用 NIO 时,JDK 5+ 的SSLEngine功能用于在连接建立后处理握手。不使用 NIO 时,使用标准的SSLSocketFactorySSLServerSocketFactory对象创建连接。提供了一些策略接口以允许进行显著的自定义。这些接口的默认实现提供了开始使用安全通信的最简单方法。

入门

无论是否使用 NIO,都需要在连接工厂上配置ssl-context-support属性。此属性引用一个<bean/>定义,该定义描述了所需密钥库的位置和密码。

SSL/TLS 对等体每个都需要两个密钥库

  • 一个密钥库,其中包含用于标识对等体的私钥和公钥对

  • 一个信任库,其中包含受信任的对等体的公钥。请参阅 JDK 提供的keytool实用程序的文档。基本步骤如下:

    1. 创建一个新的密钥对并将其存储在密钥库中。

    2. 导出公钥。

    3. 将公钥导入对等体的信任库。

    4. 对另一个对等体重复此操作。

在测试用例中,通常在两个对等体上使用相同的密钥库,但在生产环境中应避免这种情况。

建立密钥库后,下一步是将其位置指示给TcpSSLContextSupportbean,并将对该 bean 的引用提供给连接工厂。

以下示例配置了一个 SSL 连接

<bean id="sslContextSupport"
    class="o.sf.integration.ip.tcp.connection.support.DefaultTcpSSLContextSupport">
    <constructor-arg value="client.ks"/>
    <constructor-arg value="client.truststore.ks"/>
    <constructor-arg value="secret"/>
    <constructor-arg value="secret"/>
</bean>

<ip:tcp-connection-factory id="clientFactory"
    type="client"
    host="localhost"
    port="1234"
    ssl-context-support="sslContextSupport" />

DefaultTcpSSLContextSupport类还有一个可选的protocol属性,可以是SSLTLS(默认为TLS)。

密钥库文件名(前两个构造函数参数)使用 Spring 的Resource抽象。默认情况下,文件位于类路径上,但您可以使用file:前缀覆盖此设置(以在文件系统上查找文件)。

从 4.3.6 版本开始,当您使用 NIO 时,可以在连接工厂上指定ssl-handshake-timeout(以秒为单位)。此超时(默认为 30 秒)在等待数据时用于 SSL 握手期间。如果超时,则停止该过程并关闭套接字。

主机验证

从 5.0.8 版本开始,您可以配置是否启用主机验证。从 5.1 版本开始,默认情况下启用它;禁用它的机制取决于您是否正在使用 NIO。

主机验证用于确保您连接到的服务器与证书中的信息匹配,即使证书是受信任的。

使用 NIO 时,请配置DefaultTcpNioSSLConnectionSupport,例如:

@Bean
public DefaultTcpNioSSLConnectionSupport connectionSupport() {
    DefaultTcpSSLContextSupport sslContextSupport = new DefaultTcpSSLContextSupport("test.ks",
            "test.truststore.ks", "secret", "secret");
    sslContextSupport.setProtocol("SSL");
    DefaultTcpNioSSLConnectionSupport tcpNioConnectionSupport =
            new DefaultTcpNioSSLConnectionSupport(sslContextSupport, false);
    return tcpNioConnectionSupport;
}

第二个构造函数参数禁用主机验证。然后将connectionSupportbean注入到 NIO 连接工厂中。

不使用 NIO 时,配置在TcpSocketSupport

connectionFactory.setTcpSocketSupport(new DefaultTcpSocketSupport(false));

同样,构造函数参数禁用主机验证。