2

我正在编写一个服务器应用程序及其客户端应用程序,它们都使用 Netty 作为网络层。我发现自己面临从客户端向服务器发送密码的典型安全问题,因此我认为 SSL 是最安全的方式。

我知道安全聊天示例,并将使用它来相应地修改我的管道。但是,我还想在密码传输后禁用 SSL,并确认可以在服务器端节省一些宝贵的 CPU 周期,这可能正忙于许多其他客户端。ChannelPipeline文档指出:

“一旦连接,通道和管道之间的耦合是永久的;通道不能将另一条管道连接到它,也不能将当前管道与其分离。”

然后的想法是不要动态更改管道,这是被禁止的,而是以某种方式告诉管道中的SslHandler它应该在某个时候停止加密消息。我正在考虑创建一个继承自SslHandler的类,覆盖其handleDownstream函数以在通信中的某个时间点调用context.sendDownstream(evt) 。

问题 1:这是一个坏主意,即在某些时候禁用 SSL 吗?

为了允许管道中的一个块(比如Decoder)告诉另一个块(比如SslHandler)它​​应该从现在开始改变它的行为,我想我可以在我的ChannelPipelineFactorygetPipeline()中创建一个AtomicBoolean并传递它到DecoderSslHandler的构造函数。

问题2:这是一个坏主意,即在管道块之间共享状态吗?我担心我可能会在这里搞砸 Netty 的多线程:管道的块是否一次只处理一条消息?即:在拉下一条消息之前,第一个块是否等待最后一个块的完成?

编辑:

哦,我的错,这是来自我多次访问并引用这个问题的ChannelPipeline页面:

“由于ChannelPipeline是线程安全的,因此可以随时添加或删除ChannelHandler。例如,您可以在即将交换敏感信息时插入SslHandler,并在交换后将其删除。”

因此,这回答了关于即时修改管道内容的问题 2,而不是管道引用本身。

4

3 回答 3

3

您可以SslHandler从管道中删除,ChannelPipeline.remove(..)然后它应该将您的连接转换为纯文本。如果它不起作用,请提交一个错误 - 我们实际上还没有在生产中尝试过这种情况:-)

于 2012-12-03T06:02:16.173 回答
3

我不确定一旦建立就关闭 SSL 的效果,但我认为您误解了管道的可变性。一旦给定通道与管道相关联,该关联就是不可变的。但是,可以安全地修改管道中的处理程序。也就是说,您可以根据协议的需要添加和删除处理程序。因此,一旦 SSL 处理程序达到其目的,您应该能够删除它。

于 2012-11-27T10:12:56.043 回答
2

我不确定 Netty,但原则上,您确实可以在同一个 TCP 连接上继续使用普通流量。有几个缺点:

  • 只有身份验证会受到保护。MITM 可以执行用户预期之外的操作。(这在某种程度上类似于使用 HTTP Digest:凭据受到保护,但请求/响应实体不受保护。)

  • 从实现的角度来看,这很难做到正确。TLS 规范说:

    如果使用 TLS 的应用程序协议规定任何数据都可以在 TLS 连接关闭后通过底层传输进行传输,则 TLS 实现必须 close_notify在向应用层指示 TLS 连接已结束之前接收响应警报。

    这意味着您将以某种方式同步您的流以等待close_notify响应,然后再继续您的普通流量。编程模型相当复杂,SSLEngine您可能会发现不需要 Netty API 来处理这种情况。

虽然希望节省一些 CPU 周期可能是有意义的,但大部分 SSL/TLS 开销都在握手中,无论如何您都会这样做。用于数据实际加密的对称加密操作要便宜得多。(您应该尝试测量这个开销,看看它是否真的是一个问题。)

于 2012-11-27T10:38:41.183 回答