Java 7中是否有getRequestedServerNames()等效项?

时间:2016-11-23 18:05:34

标签: java ssl openssl java-7 sni

我尝试在当前项目中使用SNI模式,其中客户端启动到服务器的SSL连接。我希望我的服务器知道客户端打算连接到哪个主机/服务器名称。此服务器名称由客户端提供。我有一个ExtendedSSLSession对象,但由于我使用Java 7,我不能使用getRequestedServerNames()方法(在Java 8中引入),它实现了我正在寻找的确切功能。我目前的情况不允许我升级我的java版本。

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

我很感激任何指导。

谢谢!

1 个答案:

答案 0 :(得分:0)

那么,JDK 7和8是开源的,所以原则上你可以向后移植必要的新代码并构建你自己的版本(称之为7.5?) - 至少如果你的要求只是留在java7 API而不是/官方java7 JRE。但是,如果您正在谈论任何大量的运行时系统或应用程序,尤其是关键业务系统或应用程序,那么这可能是一件很麻烦的事情。

作为一种解决方法,我认为 - 但是没有解决所有细节 - 你可以偷偷摸摸相当于SSLSocketFactory.createSocket(Socket,InputStream,boolean),也是java8中的新功能,并且出于同样的原因,根据文档,& #39;下方&#39 ;.特别是如果你使用简单的' SSLServerSocketSSLSocket(client=false)界面:

  1. 自己接受TCP连接(显式或替代SSLServerSocket)

  2. 阅读ClientHello并解析您想要的部分,即SNI扩展

  3. Socket创建一个记住这些数据的包装器,并且还有一个包含ClientHello的byte[],当调用read时,它首先返回已经读过的ClientHello及其后从实际套接字读取,而write和其他操作照常工作

  4. 创建服务器端SSLSocket'以上'这个包装器 - 套接字并像往常一样使用它

  5. 当你想获得SNI时,例如在X509KeyManager回调中,而不是从ExtendedSSLSession查看[SSL]Socket,将Socket转发给socket instanceof MyWrapper你的包装 - 套接字,看看那里。 (你可以在SSLEngine上设置这个条件,这样当你进入java8时它会自动关闭。)

  6. 如果您使用的是SSLEngine界面,那么您已经在管理连接和I / O,所以在输入第一个输入(ClientHello)之前,您只需要执行2,3A和5:到my computer-advanced system setting-enviroment variable-add new 'GOOGLE_APPLICATION_CREDENTIALS' & json path解析它并在包装器中记住它,当你想看它时使用包装器。