2

SSLEngine 文档说明了如何正确关闭 SSL 连接。更具体地说,它提供了有关如何处理断开连接的说明:

除了有序关闭之外,还可能存在无序关闭,其中传输链路在关闭消息交换之前被切断。在前面的示例中,应用程序在尝试读取或写入非阻塞 SocketChannel 时可能会得到 -1。当你到达输入数据的末尾时,你应该调用 engine.closeInbound(),它会通过 SSLEngine 验证远程对等端已经从 SSL/TLS 角度干净地关闭,然后应用程序应该仍然尝试干净地关闭通过使用上述过程。

基本上,如果链接被切断,engine.closeInbound()应该调用。但是,此closeInbound()方法的文档表明,如果在从对等方接收到正确的关闭消息之前调用它,它将引发异常。在我看来,如果连接被切断,这个 close_notify 消息将永远不会收到,所以这个方法总是会抛出那个异常。

我做了测试,做了一个简单的关机程序,socketChannel.read()返回-1,我打电话engine.closeInbound(),我确实得到了以下异常:

javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack?

我错过了什么?文档的这两部分不是矛盾的吗?

4

2 回答 2

4

我不认为文档的这两部分相互矛盾。

当您到达输入数据的末尾时,您应该调用 engine.closeInbound()

这适用于完全关闭和切断的连接。当连接被切断时,将抛出异常(即,如果您在收到之前调用它close_notify)。如果close_notify收到(或者如果连接根本没有开始),则不会抛出此异常。

我不太确定您是如何进行简单的关机测试的,但您应该close_notify先从另一端发送(closeOutbound()例如,使用 )。在这种情况下,您不应该socketChannel.read()在获取之前收到 -1 close_notify(那时您不会得到异常)。

(以防万一,不久前有一个类似的问题。)SSLSocket

于 2014-04-16T13:21:40.477 回答
3

你误读了这个。

基本上如果链接被切断,closeInbound() 应该被调用。

它根本没有这么说。

它说该closeInbound()方法应始终在“当您到达输入数据的末尾时”调用,然后它将检测任何断开的连接。

如果close_notify没有收到它会抛出一个异常。

于 2014-04-16T22:31:48.283 回答