【问题标题】:Any way to disable SSLv2 backwards compatibility mode for Apache HttpClient?有什么方法可以禁用 Apache HttpClient 的 SSLv2 向后兼容模式?
【发布时间】:2016-01-21 18:06:27
【问题描述】:

我正在尝试使用 Apache HttpClient 4.1 连接到 HTTPS URL ....

HttpGet httpget = new HttpGet("https://federation/galaxy-class/enterprise/getSheildFrequencies");
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httpget);

在连接过程中,出现以下异常...

Caught: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

当我打开调试时,我看到以下内容..

 main, WRITE: TLSv1 Handshake, length = 81
 main, WRITE: SSLv2 client hello message, length = 110
 main, handling exception: java.net.SocketException: Connection reset

所以看起来我的客户端在 TLSv1 中进行了握手,但随后在 SSLv2 中发送了一个服务器不喜欢的客户端问候(它放弃了连接,因为它不支持 SSLv2 向后兼容模式)。

有没有办法告诉 Apache HttpClient 不要那样做?或者这是在底层 JRE 中配置的(我使用的是 1.6)?

更新

正如 bmargulies 建议的那样,我尝试创建自己的套接字工厂并将其配置为仅允许我想要的协议....

def supportedProtocols = new String[2]
supportedProtocols[0] = 'SSLv3'
supportedProtocols[1] = 'TLSv1'

 SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
    SSLContext.getDefault(),supportedProtocols,
    null,
    SSLConnectionSocketFactory.getDefaultHostnameVerifier());

  Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
    .register("http", PlainConnectionSocketFactory.getSocketFactory())
    .register("https", socketFactory)
    .build();

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
CloseableHttpClient client = HttpClients.custom().setConnectionManager(cm).build();

HttpResponse response = client.execute(httpget);

但这给出了另一个例外......

 javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair

【问题讨论】:

标签: java ssl apache-httpclient-4.x apache-httpcomponents


【解决方案1】:
  1. 使用当前版本的 http 组件
  2. 使用HttpClientBuilder
  3. 制作您自己的套接字工厂并将其配置为仅允许您想要的协议。

 Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
    .register("http", PlainSocketFactory.INSTANCE)
    .register("https", new SSLSocketFactory(sslcontext, hostnameVerifier))
    .build();

【讨论】:

    【解决方案2】:

    从 SSLContext 的启用协议中删除 SSLv2ClientHello

    【讨论】:

    • 如果你能分享一个代码示例,我将不胜感激。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-17
    • 2016-11-09
    • 2018-08-05
    • 2015-08-03
    • 1970-01-01
    • 1970-01-01
    • 2013-03-27
    相关资源
    最近更新 更多