在使用Java完成TLS握手之前,accept()是否返回?

时间:2014-08-18 12:45:45

标签: java sockets ssl handshake jsse

我正在使用Java的SSL库来保护我的应用程序之间的连接。我注意到即使握手失败,SSLServerSocket.accept()也会返回一个套接字。

  • 这是否意味着SSLServerSocket.accept()不会等到初始握手完成后?和
  • 如果没有,我该如何等待握手完成并检测握手失败的客户端?或者我可以简单地开始操作新的SSLSocket并在实际操作之前自动完成握手吗?

此外,写入和读取当前(重新)握手块的SSLSocket直到当前握手完成?如果没有,在握手插座上操作是否安全?握手和应用程序数据是否会并行发送而不会相互影响?

1 个答案:

答案 0 :(得分:4)

accept()不会发起握手,它只会返回已接受的套接字。当您开始在接受的套接字上执行I / O时,将启动握手。这是记录在案的行为:

http://docs.oracle.com/javase/7/docs/api/javax/net/ssl/SSLSocket.html

  

此连接的初始握手可以通过以下三种方式之一启动:

     
      
  • 调用明确开始握手的startHandshake,或者
  •   
  • 任何在此套接字上读取或写入应用程序数据的尝试都会导致隐式握手,或者
  •   
  • 如果当前没有有效会话,则调用getSession会尝试设置会话,并且会进行隐式握手。
  •   
     

如果握手因任何原因失败,SSLSocket将关闭,无法进行进一步的通信。

     

...

     

首次创建SSLSocket时,不会进行握手,因此应用程序可能首先设置其通信首选项:要使用的密码套件,套接字应处于客户端还是服务器模式等。但是,安全性始终由通过连接发送应用程序数据的时间。

至于握手重新谈判,这也记录在案:

http://docs.oracle.com/javase/7/docs/api/javax/net/ssl/SSLSocket.html#startHandshake()

  

如果已在连接上发送数据,则在此握手期间会继续流动。握手完成后,将通过事件发出信号。此方法对于连接上的初始握手是同步的,并在协商的握手完成时返回。某些协议可能不支持现有套接字上的多次握手,并且可能抛出IOException。