我需要为我正在开发的应用程序使用基于 TLS 的 TCP 套接字。我已经经历了几十个例子,虽然我没有问题地完成握手,但我似乎无法通过任何方式读取输入流(尝试了很多,包括 readline()、读取字符数组等)。每次我尝试时,应用程序都会在该位置冻结。如果我调试,它永远不会进入下一行代码。
在尝试的解决方案中,我决定转而使用 SSLEngine,因为这应该是 SSL 的 java.nio 的 Java 1.5 答案。然而,我发现one示例(此处:http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/samples/sslengine/SSLEngineSimpleDemo.java 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());
该实现缺少一些关键部分。即握手可以在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 的完整工作示例 http://onjava.com/pub/a/onjava/2004/11/03/ssl-nio.html
话虽如此,您应该知道 SSLEngine安卓坏了 http://code.google.com/p/android/issues/detail?id=12955。 Google 建议使用线程并根据该线程阻塞套接字。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)