SSLEngine documentation表示如何正确关闭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?
我错过了什么? Aren的文档中有哪两部分是矛盾的?
答案 0 :(得分:4)
我不认为文档的这两部分相互矛盾。
当你到达输入数据的末尾时,你应该调用engine.closeInbound()
这适用于干净关闭和切断的连接。当连接被切断时,将抛出异常(即,如果您在收到close_notify
之前调用它)。
如果收到close_notify
(或者连接根本没有开始),则不会抛出此异常。
我不太确定您是如何进行简单的关机测试的,但您应该先从另一端发送close_notify
(例如,使用closeOutbound()
)。在这种情况下,在获得socketChannel.read()
之前,您不应该从close_notify
收到-1(然后您就不会获得例外)。
(如果感兴趣的话,前一段时间有similar question on SSLSocket
。)
答案 1 :(得分:3)
你误解了这个。
基本上,如果链接被切断,则应调用closeInbound()。
根本没有这么说。
它说closeInbound()
方法始终总是当你到达输入数据的末尾时,它会检测到它任何断开的连接。
如果未收到close_notify
,则会抛出异常。