java – OpenJDK 11问题 – 客户端在最后一次UNWRAP之前完成了握手

前端之家收集整理的这篇文章主要介绍了java – OpenJDK 11问题 – 客户端在最后一次UNWRAP之前完成了握手前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我正在将我们的代码库从Oracle Java 1.8.0_131迁移到OpenJDK 11.0.1.我们有实现nio-ssl套接字通道的代码.在Java 8中,客户端/服务器握手工作正常.在Java 11中,客户端在从服务器解包最后一次握手消息之前完成握手.

为了解决这个问题,我只是在客户端和服务器之间建立连接,让它们执行SSL握手.我没有发送任何额外的数据.

我使用java 8建立连接并获取下面的输出.
然后我使用java 11编译,构建和运行相同的代码,并获得下面的其他输出.我不会改变任何代码.

我在客户端和服务器上都有一些日志记录,以显示握手中的哪一步.

日志输出Java 8 – 客户端

SSL Handshake Started
WRAP:OK -   BytesProduced=172  BytesConsumed=0
UNWRAP:OK - BytesProduced=0    BytesConsumed=2295
TASK
WRAP:OK -   BytesProduced=1815 BytesConsumed=0
WRAP:OK -   BytesProduced=269  BytesConsumed=0
WRAP:OK -   BytesProduced=6    BytesConsumed=0
WRAP:OK -   BytesProduced=85   BytesConsumed=0
UNWRAP:OK - BytesProduced=0    BytesConsumed=6
UNWRAP:OK - BytesProduced=0    BytesConsumed=85
SSL Handshake complete

日志输出Java 8 – 服务器

SSL Handshake Started
UNWRAP:OK - BytesProduced=0    BytesConsumed=172
TASK
WRAP:OK -   BytesProduced=2295 BytesConsumed=0
UNWRAP:OK - BytesProduced=0    BytesConsumed=1815
TASK
UNWRAP:OK - BytesProduced=0    BytesConsumed=269
TASK
UNWRAP:OK - BytesProduced=0    BytesConsumed=6
UNWRAP:OK - BytesProduced=0    BytesConsumed=85
WRAP:OK -   BytesProduced=6    BytesConsumed=6
WRAP:OK -   BytesProduced=85   BytesConsumed=0
SSL Handshake complete

日志输出Java 11 – 客户端

SSL Handshake Started
WRAP:OK -   BytesProduced=422  BytesConsumed=0
UNWRAP:OK - BytesProduced=0    BytesConsumed=160
TASK
WRAP:OK -   BytesProduced=6    BytesConsumed=0
UNWRAP:OK - BytesProduced=0    BytesConsumed=6
UNWRAP:OK - BytesProduced=0    BytesConsumed=2204
TASK
WRAP:OK -   BytesProduced=2067 BytesConsumed=0
SSL Handshake complete
UNWRAP:OK - BytesProduced=0    BytesConsumed=72

日志输出Java 11 – 服务器

SSL Handshake Started
UNWRAP:OK - BytesProduced=0    BytesConsumed=422
TASK
WRAP:OK -   BytesProduced=160  BytesConsumed=0
WRAP:OK -   BytesProduced=6    BytesConsumed=0
WRAP:OK -   BytesProduced=2204 BytesConsumed=0
UNWRAP:OK - BytesProduced=0    BytesConsumed=6
UNWRAP:OK - BytesProduced=0    BytesConsumed=2067
TASK
WRAP:OK -   BytesProduced=72    BytesConsumed=0
SSL Handshake complete

握手代码

engine.beginHandshake();
HandshakeStatus hs = engine.getHandshakeStatus();
while(hs != HandshakeStatus.FINISHED && hs != HandshakeStatus.NOT_HANDSHAKING){
  switch(hs){
    case NEED_WRAP:
      SSLEngineResult res = engine.wrap(myAppData,myNetData)
      hs = res.getHandshakeStatus();
      switch(res.getStatus()){
        case OK:
          // write myNetData
        case BUFFER_OVERFLOW:
          // increase size of myNetData
        case BUFFER_UNDERFLOW:
          // throw exception
        case CLOSED:
          // clean up
        default:
          // throw illegal state exception
      }
      break;
    case NEED_UNWRAP:
      boolean complete = false;
      while(!complete){
        /*
         * First handle any encrypted data left on buffer
         * If there is none,read in more
         */
        if(peerNetData.position() > 0 || channel.read(peerNetData) > 0){
          peerNetData.flip();
          res = engine.unwrap(peerNetData,peerAppData);
          hs = res.getHandshakeStatus();
          switch(res.getStatus()){
            case OK:
              complete = true;
              peerNetData.compact();
              break;
            case BUFFER_UNDERFLOW:
              // if buffer is full,increase size
              // if buffer isn't full,compact and read
            case BUFFER_OVERFLOW:
              // increase size of peerAppData
            case CLOSED:
              // cleanup
            default:
              // throw illegal state exception
          }
        }
      }
      break;
    case NEED_TASK:
      // Run task
      hs = engine.getHandshakeStatus();
      break;
    case FINISHED:
      break;
    case NOT_HANDSHAKING:
      break;
    default:
      // illegal state
  }
}

不幸的是,我的代码存在于空气密封的环境中,所以在这里粘贴它并不容易.我手动输入它,因此括号和制表符可能不对齐.

主要的一点是hs = res.getHandshakeStatus(…)在包装了2067字节之后在客户机上返回FINISHED,好像它应该返回NEED_UNWRAP.如果我将其更改为hs = engine.getHandshakeStatus(),则返回NOT_HANDSHAKING.

在服务器计算机上,hs = engine.getHandshakeStatus()在运行最后一个任务后返回NEED_WRAP,导致它最后72个字节的WRAP.

当从服务器向UNWRAP提供72字节的数据时,为什么我的客户机上的SSLEngine会给我一个握手状态“FINISHED”?有没有其他人对Java 11的自定义握手逻辑有任何问题?

最佳答案
JavaDoc of SSLEngine在类描述的末尾有一个关于并发的注释.

因此,我假设您的问题看起来像是基于竞争条件的并发问题.从JDK 8迁移到JDK 11后,如何同时调用wrap和unwrap函数可能会有所不同.您提供的示例代码没有任何synchronized语句.

如果将两个函数调用与共享对象同步,则握手应在每次最后一次解包后完成.

猜你在找的Java相关文章