2017-06-04 31 views
0

私はSSL通信を学習していましたが、この問題が発生しました。私は、ローカルのApacheサーバーとハンドシェイクしようとする単純なクライアントを書いています。サーバーはhttpsが有効です。すべての可能なトラストストア(jdk &のもの)にサーバー証明書を追加しました。しかし、ハンドシェイクの状態は決して終わっていません。継続的に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のままです。別のスレッドでタスクを処理することは、実際には非常に複雑です。少なくともインラインで動作させる方が良いでしょう。あなたも同様のことを書いてループしています。両方を修正するには、「セレクタ」との統合が必要であり、これも非常に重要ではありません。 – 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; 

に上記のコードを変更し、今ではあなたのように、多分他の人、それ以外の場合はNEED_TASKケースに変更することはできません、ループ内のハンドシェイクのステータスを取得する必要が握手

+0

ここだけでなく、ループの周りで毎回行う必要があります。 – EJP

+0

@ EJP ...はい。今あなたが何を意味するのか理解しています。私はあなたが返信として同じものを置くことができるかどうか、私はそれを回答としてマークすることができると思います。 –

関連する問題