JAVA SSLENGINE:在尝试使用SSLEngine解包bytebuffer记录时,不支持的记录版本Unknown-0.0

时间:2015-01-16 06:31:24

标签: java nio sslengine

我使用SSLEngine而不是Java NIO解锁服务器套接字来处理连接。我能够成功握手客户端并将小记录集传递给服务器。但是,当我尝试将文件传输到服务器text/binary时,我收到以下错误:

javax.net.ssl.SSLException: Unsupported record version Unknown-0.0
  at sun.security.ssl.InputRecord.checkRecordVersion(InputRecord.java:552)
  at sun.security.ssl.EngineInputRecord.bytesInCompletePacket(EngineInputRecord.java:113)
  at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:862)
  at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:775)
  at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
  at ncp.io.network.tls.TLSWrapper.unwrap(TLSWrapper.java:170)
  at ncp.io.network.tls.TLSIO.decodeData(TLSIO.java:110)
  at ncp.io.network.tls.TLSIO.handleRead(TLSIO.java:71)
  at ncp.io.network.SocketThread.run(SocketThread.java:137)

但我无法找出导致此错误的原因。

以下是我的代码段

@Override
public int handleRead(ByteBuffer temp) {

    int read = opsManager.handleRead(temp);

    if (read > 0) {

        try {
            tlsDecodeBuffer = decodeData(temp);

            try {
                temp.clear();
                temp.put(tlsDecodeBuffer);
            }catch (BufferOverflowException e){
                temp = ByteBuffer.allocateDirect(tlsDecodeBuffer.remaining());
                temp.put(tlsDecodeBuffer);
            }

            temp.flip();
            temp.rewind();

            if(tlsDecodeBuffer.hasRemaining())
                tlsDecodeBuffer.compact();
            else
                tlsDecodeBuffer.clear();

        }catch (SSLException e){
            // Error occurs here: 
            e.printStackTrace();
            log.warning("Insecure connection attempted/ SSL failure for:" + e.getMessage());
            opsManager.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }

        return read;
    } else {
        return -1;
    }
}

private ByteBuffer decodeData(ByteBuffer input) throws IOException {
    ncp.io.network.tls.TLSStatus stat = null;
    boolean continueLoop = true;

    do {

        tlsDecodeBuffer = wrapper.unwrap(input, tlsDecodeBuffer);

        switch (wrapper.getStatus()) {
            case NEED_WRITE:
                writeBuff(ByteBuffer.allocate(0));
                break;

            case UNDERFLOW:
                if (tlsDecodeBuffer.capacity() == tlsDecodeBuffer.remaining()) {
                    throw new BufferUnderflowException();
                } else {
                    input.compact();
                    continueLoop = false;
                }

                break;
            case CLOSED:
                if (log.isLoggable(Level.FINER)) {
                    log.finer("TLS Socket closed..." + toString());
                }

                throw new EOFException("Socket has been closed.");
            default:
                break;
        }

        stat = wrapper.getStatus();

    } while (continueLoop && ((stat == TLSStatus.NEED_READ) || (stat == TLSStatus.OK))
            && input.hasRemaining());

    if (continueLoop) {
        if (input.hasRemaining()) {
            input.rewind();
        } else {
            input.clear();
        }
    }

    tlsDecodeBuffer.flip();
    return tlsDecodeBuffer;
}

1 个答案:

答案 0 :(得分:0)

您的代码没有意义。

  1. 当您在BufferOverflowException中获得unwrap()时,需要通过flip()/get()/compact().

  2. 清空目标缓冲区
  3. 当您在BufferOverflowException中获得wrap()时,您需要通过flip()/write()/compact(),转到网络的write()清空目标缓冲区。

    在任何情况下都没有任何意义来分配新的缓冲区等。

  4. {li>

    rewind() flip()在任何情况下都没有意义。

    这里有很多关于如何正确使用SSLEngine的帖子和答案。我建议你仔细阅读。