Android SSLEngine的例子

时间:2012-03-30 20:10:37

标签: android sslengine

我需要在TLS上使用TCP套接字来处理我正在使用的应用程序。我已经通过了几十个例子,虽然我没有遇到握手问题,但我似乎无法通过任何方式读取输入流(尝试了很多,包括readline(),读取到字符数组等)。每次我尝试,应用程序冻结在那个位置。如果我调试,它永远不会进入下一行代码。

在尝试的解决方案中,我决定转而使用SSLEngine,因为这应该是针对SSL的java.nio的Java 1.5答案。但是,我找到了一个示例(这里: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 个答案:

答案 0 :(得分: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;
        }
    }

A full working example of Java SSL and NIO

现在说,你应该知道Android is broken上的SSLEngine。谷歌建议根据该线程使用线程和阻塞套接字。

答案 1 :(得分:1)

我已经写了一些东西,使用SSLEngine更容易。它可以与NIO一起使用或用于其他用例。 Available here SSLFacade

答案 2 :(得分:0)

如果解包的是SSL握手消息或警报而不是应用程序数据,则

unwrap()可以产生空缓冲区。这里没有足够的信息可以说更多。之后的发动机状态是什么?

答案 3 :(得分:0)

beginHandshake不进行握手,它仅用于通知SSLEngine您要为下次调用wrap / unwrap执行握手。 当你想做另一次握手时它很有用。对于初始的,不需要它,因为第一次调用wrap将启动握手。

此外,您必须检查wrap和unwrap方法的结果,以了解是否所有数据都已正确编码。可能需要多次调用方法来处理所有数据。

以下链接可能有所帮助: http://onjava.com/onjava/2004/11/03/ssl-nio.html

或者这个问题: SSL Handshaking Using Self-Signed Certs and SSLEngine (JSSE)