2015-01-16 4 views
0

Я использую SSLEngine над Java NIO разблокировать серверные сокеты для обработки соединений. Я могу успешно конфликтовать клиентов и передавать на сервер небольшие наборы записей. Однако, когда я пытаюсь передать файл на сервер text/binary я получаю следующее сообщение об ошибке:JAVA SSLENGINE: Неподдерживаемая версия записи Неизвестно-0.0 при попытке развернуть запись байтового буфера с помощью SSLEngine

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; 
} 
+0

Пожалуйста, проверьте эту ссылку: http://stackoverflow.com/questions/26166121/unsupported-record-version-sslv2hello-using-closeablehttpclient это поможет вам. –

ответ

0

Ваш код не имеет смысла.

  1. Когда вы получаете BufferOverflowException в unwrap(), вам нужно очистить целевой буфер через flip()/get()/compact().

  2. Когда вы получаете в wrap() в BufferOverflowException, вам нужно очистить целевой буфер через flip()/write()/compact(), где write() идет к сети.

    Ни в одном случае не может быть никакого смысла выделять новый буфер и т.д.

  3. rewind() после flip() не начинает иметь смысл в любом контексте.

Существует множество сообщений и ответов здесь о том, как правильно использовать SSLEngine. Я предлагаю вам внимательно их прочитать.