【发布时间】: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,而是做一个
- 修改我的
SSLContext的一组协议,这是SSLSocketImpl用来配置自己的。但是我看不到执行此操作的公共接口,因此我需要通过反射来更改它,这意味着假设类的私有成员并且还可以访问内部类ProtocolList。 - 仅使用我的
SSLContext来获取我可以配置的SSLEngine,然后使用它在套接字上实现我自己的 SSL。
我对其中任何一个都不满意;我可能会倾向于反射,因为 Java 7+ 正在放弃 SSLv2Hello,所以如果将来类发生变化并且我的反射中断,那么这实际上不是问题。我已经有一个新的 SSLContext 实例用于自定义信任存储。
我是否遗漏了什么——SSLContext 或 SSLSocketFactory 上的公共机制来设置它?有没有更好、更清洁的方法来做到这一点?谢谢!
在进一步调查中,我认为也不可能进行反思。我一直在查看 JDK8 源代码,因为这是我必须提供的,而在 JDK6 源代码中 SSLSocket initialises itself from a static list,而不是来自 SSLContext 或 SSLContextSpi 属性:
enabledProtocols = ProtocolList.getDefault();
getDefault 后面的源字段是 static final 所以我也不能修改它:-(
所以我的想法已经不多了。我仍然不热衷于重新实现 SSLSocket(超过 2000 行),所以我认为它回到了 setEnabledProtocols,并希望我的 HTTPS 客户端永远不必协商与 SSL 的连接。
【问题讨论】:
标签: java