当前位置: 首页 > 知识库问答 >
问题:

JAVA SSLEngine:尝试用SSLEngine解包bytebuffer记录时,不支持的记录版本未知-0.0

许彭祖
2023-03-14
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个答案

子车雅珺
2023-03-14

你的代码没有意义。

>

  • unwrap()中获得BufferOverflowException时,需要通过Flip()/get()/Compact()清空目标缓冲区。

    当您在wrap()中获得bufferoverflowexception时,您需要通过flip()/write()/compact()清空目标缓冲区,其中write()将进入网络。

    在这两种情况下,分配一个新的缓冲区等都没有任何意义。

    flip()之后的rewind()在任何上下文中都没有意义。

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

  •  类似资料: