6

作業中のアプリの TLS 経由で TCP ソケットを使用する必要があります。私は何十もの例を経験してきましたが、ハンドシェイクを通過するのに問題はありませんが、入力ストリームを何らかの手段で読み取ることができないようです (readline()、文字配列への読み取りなどを含む多くのことを試しました)。試すたびに、アプリはその場でフリーズします。デバッグすると、コードの次の行に進みません。

試行された解決策として、SSL 用の java.nio に対する Java 1.5 の回答であるはずの SSLEngine の使用に移行することにしました。ただし、1 つの例を見つけました (ここ: http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/samples/sslengine/SSLEngineSimpleDemo.java )。私はそれを実装することに成功していません。試してみると、 unwrap() 呼び出しによって空のバッファーが生成され、(コマンド ラインで OpenSSL を使用して) 問題のサービスがデータをパイプにプッシュしていることがわかります。

提案は大歓迎です。私はすでにこれに多くの時間を費やしてきました。関連するコードは次のとおりです。

SSLEngine engine = sslContext.createSSLEngine(uri.getHost(), uri.getPort());
            engine.setUseClientMode(true);
            engine.beginHandshake();
            SSLSession session = engine.getSession();
            int bufferMax = session.getPacketBufferSize();
            int appBufferMax = session.getApplicationBufferSize() + 50;
            ByteBuffer cTo = ByteBuffer.allocateDirect(bufferMax);
            ByteBuffer sTo = ByteBuffer.allocateDirect(bufferMax);

            ByteBuffer out = ByteBuffer.wrap(sessionId.getBytes());
            ByteBuffer in = ByteBuffer.allocate(appBufferMax);


            debug("sending secret");
            SSLEngineResult rslt = engine.wrap(out, cTo);
            debug("first result: " + rslt.toString());
            sTo.flip();
            rslt = engine.unwrap(sTo, in);
            debug("next result" + rslt.toString());
4

4 に答える 4

1

この実装には、いくつかの重要な部分が欠けています。つまり、ハンドシェイクは、接続をネゴシエートするために、いくつかの状態 NEED_WRAP、NEED_UNWRAP、NEED_TASK の間でバウンスできます。つまり、一方を呼び出してから他方を呼び出すことはできません。ハンドシェイクが完了するまで、状態をループする必要があります。

   while (handshaking) {
      switch (state) {
          case NEED_WRAP:
              doWrap();
              break;
          case NEED_UNWRAP:
              doUnwrap();
              break;
          case NEED_TASK:
              doTask();
              break;
        }
    }

Java SSL と NIO の完全な動作例

そうは言っても、 Androidの SSLEngine は壊れていることに注意してください。Google では、スレッドを使用し、そのスレッドに従ってソケットをブロックすることをお勧めします。

于 2012-10-31T16:32:28.097 に答える
1

SSLEngine の使用を簡単にするために何かを書きました。NIO またはその他のユースケースで使用できます。ここから入手可能 SSLFacade

于 2013-06-25T17:51:37.400 に答える
0

beginHandshakeはハンドシェイクを続行しません。次のラップ/アンラップ呼び出しでハンドシェイクを実行することを SSLEngine に通知するためにのみ使用されます。もう一度握手をしたいときに便利です。最初の場合は、wrap への最初の呼び出しでハンドシェイクが開始されるため、必要ありません。

さらに、wrap メソッドと unwrap メソッドの結果をチェックして、すべてのデータが正しくエンコードされているかどうかを確認する必要があります。すべてのデータを処理するために、メソッドを数回呼び出す必要がある場合があります。

次のリンクが役立つ場合があります: http://onjava.com/onjava/2004/11/03/ssl-nio.html

または、この質問: 自己署名証明書と SSLEngine (JSSE) を使用した SSL ハンドシェイク

于 2012-07-20T12:48:12.353 に答える
0

unwrap()アンラップされたものがアプリケーション データではなく、SSL ハンドシェイク メッセージまたはアラートであった場合、空のバッファが生成される可能性があります。これ以上語れるほどの情報はありません。その後のエンジンの状態は?

于 2012-04-02T03:56:14.867 に答える