java - Java 7 中是否有等效的 getRequestedServerNames()?

标签 java ssl openssl java-7 sni

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

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

如有任何指导,我将不胜感激。

谢谢!

最佳答案

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

作为一种解决方法,我认为——但还没有制定出所有的细节——你可以偷偷相当于 SSLSocketFactory.createSocket(Socket,InputStream,boolean) ,也是 java8 中的新内容,根据文档“underneath”出于同样的原因。特别是如果您使用的是“简单”SSLServerSocketSSLSocket(client=false)接口(interface):

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

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

  3. Socket 创建包装器记住这些数据,还有类似 byte[] 的东西包含 ClientHello 和 when read被调用它首先返回已经读取的 ClientHello 然后从实际套接字读取,而 write其他操作照常进行

  4. 创建服务器端SSLSocket “在”这个包装器套接字之上并像往常一样使用它

  5. 当您想获取 SNI 时,例如在 X509KeyManager 中回调,而不是查看 ExtendedSSLSession来自 [SSL]Socket , 垂头丧气Socket到您的包装器套接字并查看那里。 (您可以在 socket instanceof MyWrapper 上设置此条件,这样当您进入 java8 时它会自行关闭。)

如果您使用 SSLEngine接口(interface),您已经在管理连接和 I/O,所以您只需要执行 2、3A 和 5: 在将第一个输入 (ClientHello) 提供给 SSLEngine 之前解析它并在包装器中记住它,当你想查看它时使用包装器。

关于java - Java 7 中是否有等效的 getRequestedServerNames()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40771429/

相关文章:

web-services - 在 Delphi Web 服务中使用 OpenSSL - 可用协议(protocol)和密码

delphi - 在Delphi中使用OpenSSL验证SHA256签名失败

node.js - EVP_DecryptFinal_ex :bad decrypt when using Node. js

java - 如何使用 WSO2 ESB 4.7 中的 SOAP 服务 addSequence

java - 通过类路径 Spring 访问 war tomcat 中依赖项 jar 中的属性文件

java - 简单的 java 程序在 Eclipse 中没有输出

Java 泛型放在 Map<String, ?扩展列表<String>>

asp.net-mvc - 如何使用 Fluent Security 在 ASP.net MVC 应用程序中设置 SSL 重定向?

maven - 目标特定的 javax.net.ssl.trustStore

c# - 使用 https 和验证的 WCF 安全身份验证