【问题标题】:Does accept() return before TLS handshake is done in Java?在 Java 中完成 TLS 握手之前,accept() 会返回吗?
【发布时间】:2014-08-18 12:45:45
【问题描述】:

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

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

另外,当前(重新)握手的 SSLSocket 的写入和读取是否会阻塞,直到当前握手完成?如果不是,在握手套接字上操作是否安全?握手和应用程序数据会并行发送并且不会相互影响吗?

【问题讨论】:

    标签: java sockets ssl handshake jsse


    【解决方案1】:

    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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-02
      • 1970-01-01
      • 2021-03-15
      • 1970-01-01
      • 2011-06-24
      • 2020-08-04
      • 1970-01-01
      • 2021-05-22
      相关资源
      最近更新 更多