【问题标题】:Change enabled protocols for Java SSL client connections, including wrapped case更改 Java SSL 客户端连接的启用协议,包括包装案例
【发布时间】:2013-12-08 18:28:23
【问题描述】:

我需要实现 Apache HttpClient SecureProtocolSocketFactory 接口来创建不使用 SSLv2Hello 协议的 SSL 套接字并进行 SSLv3 握手。从the documentation,修改协议列表的过程是在SSLSocket上调用setEnabledProtocols。我相信我需要在创建它之后但在连接它之前执行此操作,因为连接会启动 SSL 握手,这是我尝试更改的 SSL 握手协议。

这基本没问题:与其使用带有参数的context.getSocketFactory().createSocket(...) 重载来创建和连接套接字,那么我可以使用无参数重载来创建套接字,设置它然后自己连接它。问题是 another overload of createSocket() in SSLSocketFactory 使用 SSL 包装现有套接字,并立即启动握手,即我没有机会重新配置它。

所以为了解决这个问题,我想我必须扔掉SSLSocket.setEnabledProtocols,而是做一个

  1. 修改我的SSLContext 的一组协议,这是SSLSocketImpl 用来配置自己的。但是我看不到执行此操作的公共接口,因此我需要通过反射来更改它,这意味着假设类的私有成员并且还可以访问内部类ProtocolList
  2. 仅使用我的SSLContext 来获取我可以配置的SSLEngine,然后使用它在套接字上实现我自己的 SSL。

我对其中任何一个都不满意;我可能会倾向于反射,因为 Java 7+ 正在放弃 SSLv2Hello,所以如果将来类发生变化并且我的反射中断,那么这实际上不是问题。我已经有一个新的 SSLContext 实例用于自定义信任存储。

我是否遗漏了什么——SSLContextSSLSocketFactory 上的公共机制来设置它?有没有更好、更清洁的方法来做到这一点?谢谢!


在进一步调查中,我认为也不可能进行反思。我一直在查看 JDK8 源代码,因为这是我必须提供的,而在 JDK6 源代码中 SSLSocket initialises itself from a static list,而不是来自 SSLContextSSLContextSpi 属性:

enabledProtocols = ProtocolList.getDefault();

getDefault 后面的源字段是 static final 所以我也不能修改它:-(

所以我的想法已经不多了。我仍然不热衷于重新实现 SSLSocket(超过 2000 行),所以我认为它回到了 setEnabledProtocols,并希望我的 HTTPS 客户端永远不必协商与 SSL 的连接。

【问题讨论】:

    标签: java


    【解决方案1】:

    我遇到了非常相似的问题。 我认为您可以将大部分问题分解为一个问题,为什么我们可以在自定义套接字工厂中覆盖启用的密码,但我们无法设置 getEnabledProtocols(): String[] 返回的协议版本?

    或者更简单: 如果您可以在 SSLContext 中设置启用的密码和协议版本,您可以使用任何 HttpsConnection / SSLClient 和 SSLServerSocket 甚至库(Apache HttpClient,OKHttp,...),并确保您在 SSL 协议版本和密码方面的安全要求是都认识了。

    不幸的是,大多数人在建立连接的时候就停下来了,安全只是对他们的一个声明。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-15
      • 2011-04-24
      • 1970-01-01
      • 1970-01-01
      • 2019-03-11
      相关资源
      最近更新 更多