2017-06-04 146 views
0

我正在學習SSL通信,並且遇到了這個問題。我正在寫一個簡單的客戶端,它試圖與本地apache服務器握手。該服務器已啓用https。我將服務器證書添加到所有可能的信任存儲(也是該程序使用的jdk &中的一個)。但握手狀態永遠不會達到FINISHED。它一直處於NEED_TASK狀態 第一次進入循環時,我得到一個sun.security.ssl.Handshaker $ DelegatedTask。此後,狀態爲NEED_TASK,任務爲空。 。下面的代碼我的理解錯誤\缺陷在哪裏?SSL握手失敗Java

注:我從下面的教程中的代碼:

http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html#KRB

這是停留在NEED_TASK狀態握手代碼如下:

void doHandshake(SocketChannel socketChannel, SSLEngine engine, 
      ByteBuffer myNetData, ByteBuffer peerNetData) throws Exception { 

     // Create byte buffers to use for holding application data 
     int appBufferSize = engine.getSession().getApplicationBufferSize(); 
     ByteBuffer myAppData = ByteBuffer.allocate(appBufferSize); 
     ByteBuffer peerAppData = ByteBuffer.allocate(appBufferSize); 
     // Begin handshake 
     engine.beginHandshake(); 
     SSLEngineResult.HandshakeStatus hs = engine.getHandshakeStatus(); 
     int i=0; 
     // Process handshaking message 
     while (hs != SSLEngineResult.HandshakeStatus.FINISHED && 
      hs != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) { 
      i++; 
      switch (hs) { 

      case NEED_UNWRAP: 
       // Receive handshaking data from peer 
       if (socketChannel.read(peerNetData) < 0) { 
        // The channel has reached end-of-stream 
       } 

       // Process incoming handshaking data 
       peerNetData.flip(); 
       SSLEngineResult res = engine.unwrap(peerNetData, peerAppData); 
       peerNetData.compact(); 
       hs = res.getHandshakeStatus(); 

       // Check status 
       switch (res.getStatus()) { 
       case OK : 
        // Handle OK status 
        break; 

       // Handle other status: BUFFER_UNDERFLOW, BUFFER_OVERFLOW, CLOSED 

       } 
       break; 

      case NEED_WRAP : 
       // Empty the local network packet buffer. 
       myNetData.clear(); 

       // Generate handshaking data 
       res = engine.wrap(myAppData, myNetData); 
       hs = res.getHandshakeStatus(); 

       // Check status 
       switch (res.getStatus()) { 
       case OK : 
        myNetData.flip(); 

        // Send the handshaking data to peer 
        while (myNetData.hasRemaining()) { 
         socketChannel.write(myNetData); 
        } 
        break; 

       // Handle other status: BUFFER_OVERFLOW, BUFFER_UNDERFLOW, CLOSED 

       } 
       break; 

      case NEED_TASK : 
       Runnable task =engine.getDelegatedTask(); 
       if(task!= null) { 
        //task.run(); 
        new Thread(task).start(); 
       }// Handle blocking tasks 

       break; 

      // Handle other status: // FINISHED or NOT_HANDSHAKING 

      } 
     } 
     // Processes after handshaking 

    } 

任何幫助,將不勝感激。

+0

你需要得到循環內的握手狀態,否則它不可能在NEED_TASK情況發生變化,也許別人的好。狀態將保持NEED_TASK狀態,直到任務完成。在一個單獨的線程中處理任務確實非常複雜。你可能會更好地運行它,直到你至少工作。通過循環寫入,你正在做類似的事情。解決這兩個問題都需要與一個'Selector'集成,這也是非常重要的。 – EJP

+0

@EJP這個任務應該做什麼?這個任務被卡住了,因爲我沒有將服務器證書添加到任何信任存儲?我只想達到握手的完成狀態。那是我現在唯一的目標。這個選擇器概念有一些教程或起始頁嗎? –

+0

它與信任庫有關,不知道是什麼。 – EJP

回答

0

問題是我對engine.getHandShakeStatus()方法的不完全理解。

我改變了上面的代碼

case NEED_TASK : 
      Runnable task =engine.getDelegatedTask(); 
      if(task!= null) { 
       //task.run(); 
       new Thread(task).start(); 
      } 
      hs = engine.getHandshakeStatus(); 
      break; 

而現在完成了握手

+0

你需要在循環中每次都做,而不只是在這裏。 – EJP

+0

@EJP ...是的。現在我明白你的意思了。我想如果你可以把答案放在同一位置,我可以將其標記爲答案。 –