비 차단 socketChannel 및 SSLEngine을 사용하고 있습니다. 그래서 성공적인 핸드 셰이크 후 소켓 (184 바이트/384 바이트를 처음 읽는 중)을 읽은 다음이 버퍼를 unwrap 메서드에 전달합니다. 언랩 방법은 다음과 같은 예외 던져 :SSLEngine : 성공적인 핸드 셰이크 후 래핑 해제시 TLS 패딩 데이터가 올바르지 않습니다.
javax.net.ssl.SSLHandshakeException: Invalid TLS padding data
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLEngineImpl.fatal(Unknown Source)
at sun.security.ssl.SSLEngineImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLEngineImpl.readNetRecord(Unknown Source)
at sun.security.ssl.SSLEngineImpl.unwrap(Unknown Source)
at javax.net.ssl.SSLEngine.unwrap(Unknown Source)
을하지만 경우에 그때 내가이 예외를 얻을하지 않습니다 처음에 모든 바이트 (384분의 384)를 참조하십시오.
sslengine에 unwrap 할 바이트가 충분하지 않으면 bufferUnderflow 상태가 반환 될 것이라고 생각했습니다.
unwrap 메서드를 호출하기 위해 실제로 모든 바이트가 필요합니까? 그렇다면 어떻게 비 블로킹 소켓의 모든 바이트를 읽을 수 있습니까?
편집 : 코드 :
public boolean doHandShake(SocketChannel socket) throws Exception{
if(!socket.isConnected()){
return false;
}
outAppData.clear();
inAppData.clear();
inNetData.clear();
outNetData.clear();
if(engine==null || socket==null)
return false;
engine.beginHandshake();
SSLEngineResult.HandshakeStatus hs = engine.getHandshakeStatus();
while (hs != SSLEngineResult.HandshakeStatus.FINISHED &&
hs != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
switch (hs) {
case NEED_UNWRAP:
int read=1;
while (read > 0) {
read=socket.read(inNetData);
if(read==-1){
throw new IOException ("channel closed");
}
}
inNetData.flip();
engineRes=engine.unwrap(inNetData, outAppData);
inNetData.compact();
switch(engineRes.getStatus()){
case BUFFER_OVERFLOW:
System.out.println("overFlow");
break;
case CLOSED:
return false;
case OK:
//outAppData.clear();
// inNetData.clear();
break;
default:
break;
}
break;
case NEED_WRAP :
outNetData.clear();
engineRes=engine.wrap(inAppData, outNetData);
outNetData.flip();
switch (engineRes.getStatus()){
case BUFFER_OVERFLOW:
System.out.println("overFlow");
break;
case BUFFER_UNDERFLOW:
System.out.println("underFlowa");
break;
case CLOSED:
return false;
case OK:
//outNetData.flip();
while(outNetData.hasRemaining()){
if(socket.write(outNetData)<0){
throw new Exception("Channel Has been Closed");
}
}
break;
default:
break;
}
break;
case NEED_TASK :
Runnable r=engine.getDelegatedTask();
r.run();
break;
case FINISHED:
System.out.println("finished");
break;
case NOT_HANDSHAKING:
break;
default:
throw new IllegalArgumentException("Inexpected/Unhadled SSLEngineResult :"+hs);
}
hs = engine.getHandshakeStatus();
}
return true;
}
는 내가 아닌 차단 채널을 사용하여 384분의 184 바이트를 읽습니다.
read = _socketChannel.read (buffer);
다음에 buffer
패스가 해독 될 :
public ByteBuffer decrypt(ByteBuffer inNetData) throws SSLException{
if(!isValidSession()){
return null;
}
outAppData.clear();
try{
engineRes=engine.unwrap(inNetData, outAppData);
}catch(Exception e){
e.printStackTrace();
}
inNetData.compact();
switch(engineRes.getStatus()){
case BUFFER_OVERFLOW:
outAppData=ByteBuffer.allocate(outNetData.capacity()*2);
inNetData.position(0);
return encrypt(inNetData);
case BUFFER_UNDERFLOW:
return null;
case CLOSED:
return null;
case OK:
outAppData.flip();
System.out.println(new String(outAppData.array(),0,400));
return outAppData;
default:
break;
}
return null;
}
engineRes = engine.unwrap (inNetData, outAppData);
몇 가지 코드를 게시하십시오. – EJP
완료.제발 도움이 – user3791570