SSL and SocketChannel

13

理想情况下,我只需要一个简单的SSLSocketChannel

我已经有一个组件可通过普通的SocketChannel读写消息,但是对于其中一些连接,我必须在传输过程中使用SSL;然而,这些连接上的操作是相同的。

是否有人知道一个免费的SSLSocketChannel实现(带有适当的选择器)或类似物?我找到了这个,但选择器不接受它,因为其供应商不是SUN。

我正在将网络逻辑的读取和写入与通过一个简单对象插入和检索网络数据分离开来,以便使用SSLEngine而不会发疯,但是要正确实现这一点真的很棘手,因为我不知道SSL协议的内部原理...

4个回答

5
Jetty为其服务器提供了一种NIO SSL实现:SslSelectorChannelConnector。您可以查看它以获取详细信息。
此外,O'Reilly有一篇旧的(但不错)文章,解释了NIO + SSL的细节,并提供了示例代码。

1
谢谢你的建议 :) 我已经了解了O'Reilly文章,但它有点太简单了。我在Esmond Pitt的书《Java基础网络编程》中发现了一个非常好的建议,可以构建类似于SSLSocketChannel的东西,但仍然很痛苦去正确地获取它;) - akappa

3

TLS Channel 是一个简单的库,它可以包装 SSLContext(或 SSLEngine),并公开一个 ByteChannel 接口,在内部完成大量工作。

(免责声明:我是该库的主要作者)。


0

不确定这是否是您要找的,但可能会有所帮助... 要创建启用SSL/TLS的服务器套接字,我目前正在使用类似以下代码的方式(keystore.jks包含用于安全确认的自签名私钥/公钥对)- 客户端具有类似的信任存储库,其中包含带有该对的公钥的已签名证书。

通过一些谷歌搜索来配置它应该能帮助您入门。

String keyStorePath = "keystore.jks";
String keyStorePassword = "password";

KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
KeyStore keyStore = new KeyStore();
keyStore.load(new FileInputStream(keyStorePath), keyStorePassword);
keyManagerFactory.init(keyStore, keyStorePassword.toCharArray());

sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());

SSLContext sslContext = getServerSSLContext(namespace.getUuid());
SSLServerSocketFactory serverSocketFactory = sslContext.getServerSocketFactory();

// Create sockets as necessary

3
也许从问题中不太清楚,但是我有一个执行非阻塞I/O的组件,因此我想要一个非阻塞的SSL套接字(在Java中,非阻塞套接字称为“通道”)。通过你的方法,你拥有一个通过SSL/TLS加密数据的阻塞式Socket,所以这不是我要寻找的东西。我在另一个组件中使用这种方法,那里我可以负担每个连接一个线程的开销。无论如何,感谢您的时间! - akappa
我最近也考虑过类似的事情,最终决定使用 http://www.jboss.org/netty 和 http://mina.apache.org 这样的工具来更轻松地将 SSL 添加到 NIO 中。虽然有一些机制可以通过从 SSLContext 获取的 SSL 引擎来使用 NIO,但是看了一下可用的示例代码,发现它太难了!(我的经验法则是,如果我需要下载一个源代码的 ZIP 文件作为教程(而不是内联显示),那么就是寻找替代方案的时候了……) - Martin

0

请查看Restlet的实现,它可能满足您的需求,并且它完全基于NIO。

Restlet Engine Javadoc

具体来说,是HttpClientCall。SetProtocol(HTTPS)-getResponseEntityChannel返回一个ReadableByteChannel(getEntityChannel返回一个WriteableByteChannel)


嗯,我已经在源代码中搜索了“SSLEngine”,但没有找到任何结果...也许他们没有使用非阻塞I/O和SSL? - akappa
我有所怀疑 - 整个Restlet项目都是基于NIO的。很抱歉帮不上更多忙,但我相信他们一定在其中有一个NIO SSL解决方案。 - Gandalf
事实是我几乎怀疑他们自己实现了类似于SSLEngine的东西,所以他们应该使用SSLEngine来获得通道上的安全连接...顺便说一下,我会更仔细地看一下:P - akappa
那个链接已经死了将近四年了。这个(2.2)目前似乎可以使用:http://www.restlet.org/documentation/2.2/jee/engine/org/restlet/engine/adapter/ClientCall.html - Jay Taylor
1
因为这个答案完全没有帮助,也没有提供任何有用的见解,所以被踩了。 - Jay Taylor
2
链接无法使用,如果你能找到源代码的话,它也没有指向任何有用的内容。 - Ryan Pfeffer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接