2016-11-23 113 views
2

我想在当前项目中使用SNI模式,其中客户端启动到服务器的SSL连接。我希望我的服务器知道客户端打算连接的主机/服务器名称。该服务器名称由客户端提供。我有一个ExtendedSSLSession对象,但是因为我使用的是Java 7,所以我无法使用getRequestedServerNames()方法(它是在Java 8中引入的),它实现了我正在寻找的确切功能。我目前的情况不允许我升级我的Java版本不幸的。在Java 7中是否有一个getRequestedServerNames()等价物?

我想问问社区在使用Java 7时是否有解决方法来获取服务器名称?

我将不胜感激任何指导。

谢谢!

+0

另请参见[如何实现服务器名称指示(SNI)](http://stackoverflow.com/q/5113333),[在SNI中在一个框中提供多个域](http://stackoverflow.com/q/22373332)和[SSL_CTX_set_tlsext_servername_callback回调函数未被调用](http://stackoverflow.com/q/22607121)。 – jww

+0

对不起,请允许我告诉我如何使用这些信息?他们似乎使用SSL_get_servername,我认为这是我希望在Java 7中找到的实现?谢谢! –

+0

他们是OpenSSL调用。为什么这个问题有OpenSSL标签? – jww

回答

0

那么,JDK 7和8是开源的,所以原则上你可以回溯必要的新代码并构建你自己的版本(称为7.5?) - 至少如果你的要求只是停留在java7 API上/一个官方的java7 JRE。但是如果您正在讨论大量运行时系统或应用程序,特别是关键业务系统或应用程序,那么这可能是一个麻烦。

作为一种解决方法,我认为 - 但还没有制定出所有细节 - 您可以潜行相当于SSLSocketFactory.createSocket(Socket,InputStream,boolean),在java8中也是新的,并且出于同样的原因,根据文档'underneath'。具体来说,如果您使用的是“简单” SSLServerSocketSSLSocket(client=false)接口:

  1. 接受自己(无论是明示或在SSLServerSocket更换)

  2. 阅读客户问候,并解析块TCP连接(S )你想,即在SNI扩展

  3. 创建一个包装为Socket可以记住这个数据,也有包含客户问候,并像一个byte[]read把它叫做第一返回已读客户问候后,从实际插槽读取,而write等操作照常上班

  4. 创建一个服务器端SSLSocket“上面”这个封装,Socket和使用它像往常一样

  5. 时你想获得SNI,例如在X509KeyManager回调中,而不是从[SSL]Socket查看ExtendedSSLSession,将Socket向下翻转到你的包装套接字并在那里查看。 (你可以把这个条件上socket instanceof MyWrapper所以它自行关闭,当你获得到java8。)

如果您使用的是SSLEngine界面,你已经在管理连接和I/O,所以你只需要执行2,3A和5:在将第一个输入(ClientHello)提供给SSLEngine进行解析并将其记忆在包装中之前,以及何时使用包装来查看它。

相关问题