代码之家  ›  专栏  ›  技术社区  ›  deamon

如何使用Apache HttpClient启用SSLv3?

  •  6
  • deamon  · 技术社区  · 10 年前

    在Apache中禁用SSLv3 HttpClient 从4.3.6版开始,但我使用的是4.5版 developers wrote :

    希望继续使用SSLv3的用户需要明确启用对它的支持。

    我试图在JVM级别设置受支持的协议,但没有成功。示例在Scala中,但这与问题无关:

    System.setProperty("https.protocols", "SSLv2Hello,SSLv3,TLSv1,TLSv1.1,TLSv1.2")
    

    我的第二次尝试是:

    val instance: CloseableHttpClient = {
      val trustStrategy = new TrustStrategy {
        override def isTrusted(x509Certificates: Array[X509Certificate], s: String) = true
      }
      val sslContext = new SSLContextBuilder().loadTrustMaterial(null, trustStrategy).build()
      val sslSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE)
      val socketFactoryRegistry =
        RegistryBuilder.create[ConnectionSocketFactory]()
            .register("http", PlainConnectionSocketFactory.getSocketFactory)
            .register("https", sslSocketFactory)
            .build()
      val connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry)
      HttpClients.custom()
          .disableRedirectHandling()
          .setSSLContext(sslContext)
          .setConnectionManager(connectionManager)
          .build()
    }
    

    但它也不起作用。

    如何使用Apache HttpClient 4.5连接到支持SSLv2Hello、SSLv3、TLSv1、TLSv1.1、TLSv1.2的主机?

    1 回复  |  直到 10 年前
        1
  •  6
  •   ok2c    10 年前

    默认情况下,HttpClient不考虑系统属性。需要指示HttpClient生成器这样做

    CloseableHttpClient client = HttpClients.createSystem();
    

    或使用自定义协议设置手动配置连接套接字工厂

    SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
            SSLContext.getDefault(),
            new String[] { "SSLv2Hello","SSLv3","TLSv1","TLSv1.1","TLSv1.2"},
            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();
    

    编辑

    此代码片段与注释中提到的站点配合得很好

    SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
            SSLContext.getDefault(),
            new String[] {"TLSv1"},
            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();
    try (CloseableHttpResponse response = client.execute(new HttpGet("https://www.ethz.ch/de.html"))) {
        System.out.println(response.getStatusLine());
        System.out.println(EntityUtils.toString(response.getEntity()));
    }