📜  Apache HttpClient-自定义SSL上下文

📅  最后修改于: 2020-11-18 08:31:56             🧑  作者: Mango


使用安全套接字层,可以在客户端和服务器之间建立安全连接。它有助于保护敏感信息,例如信用卡号,用户名,密码,密码等。

通过使用HttpClient库创建自己的SSL上下文,可以使连接更安全。

请按照下面给出的步骤使用HttpClient库自定义SSLContext-

第1步-创建SSLContextBuilder对象

SSLContextBuilder是SSLContext对象的构建器。使用SSLContexts类的custom()方法创建其对象。

//Creating SSLContextBuilder object
SSLContextBuilder SSLBuilder = SSLContexts.custom();

第2步-加载密钥库

在路径Java_home_directory / jre / lib / security /中,您可以找到一个名为cacerts的文件。将其另存为密钥存储文件(扩展名为.jks)。使用SSLContextBuilder类的loadTrustMaterial()方法加载密钥库文件及其密码(默认情况下为changeit )。

//Loading the Keystore file
File file = new File("mykeystore.jks");
SSLBuilder = SSLBuilder.loadTrustMaterial(file, "changeit".toCharArray());

第3步-构建SSLContext对象

SSLContext对象表示安全套接字协议实现。使用build()方法构建一个SSLContext。

//Building the SSLContext
SSLContext sslContext = SSLBuilder.build();

第4步-创建SSLConnectionSocketFactory对象

SSLConnectionSocketFactory是用于TSL和SSL连接的分层套接字工厂。使用此功能,您可以使用信任证书列表来验证Https服务器并验证给定的Https服务器。

您可以通过多种方式创建它。根据创建SSLConnectionSocketFactory对象的方式,可以允许所有主机,仅允许自签名证书,仅允许特定协议,等等。

若要仅允许特定协议,请通过传递SSLContext对象来创建SSLConnectionSocketFactory对象,表示协议的字符串数组需要受支持,表示密码组的字符串数组需要受支持,并且将HostnameVerifier对象传递给其构造函数。

new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null,    
   SSLConnectionSocketFactory.getDefaultHostnameVerifier());

要允许所有主机,请通过传递SSLContext对象和NoopHostnameVerifier对象来创建SSLConnectionSocketFactory对象。

//Creating SSLConnectionSocketFactory SSLConnectionSocketFactory object
SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslcontext, new NoopHostnameVerifier());

第5步-创建HttpClientBuilder对象

使用HttpClients类的custom()方法创建HttpClientBuilder对象。

//Creating HttpClientBuilder
HttpClientBuilder clientbuilder = HttpClients.custom();

第6步-设置SSLConnectionSocketFactory对象

使用setSSLSocketFactory()方法将SSLConnectionSocketFactory对象设置为HttpClientBuilder

//Setting the SSLConnectionSocketFactory
clientbuilder = clientbuilder.setSSLSocketFactory(sslConSocFactory);

第7步-构建CloseableHttpClient对象

通过调用build()方法来构建CloseableHttpClient对象。

//Building the CloseableHttpClient
CloseableHttpClient httpclient = clientbuilder.build();

步骤8-创建一个HttpGet对象

HttpGet类表示HTTP GET请求,该请求使用URI检索给定服务器的信息。

通过传递表示URI的字符串实例化HttpGet类来创建HTTP GET请求。

//Creating the HttpGet request
HttpGet httpget = new HttpGet("https://example.com/");

第9步-执行请求

使用execute()方法执行请求。

//Executing the request
HttpResponse httpresponse = httpclient.execute(httpget);

以下示例演示了SSLContrext的定制-

import java.io.File;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

public class ClientCustomSSL {
   
   public final static void main(String[] args) throws Exception {

      //Creating SSLContextBuilder object
      SSLContextBuilder SSLBuilder = SSLContexts.custom();
  
      //Loading the Keystore file
      File file = new File("mykeystore.jks");
      SSLBuilder = SSLBuilder.loadTrustMaterial(file,
         "changeit".toCharArray());

      //Building the SSLContext usiong the build() method
      SSLContext sslcontext = SSLBuilder.build();
 
      //Creating SSLConnectionSocketFactory object
      SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslcontext, new NoopHostnameVerifier());
 
      //Creating HttpClientBuilder
      HttpClientBuilder clientbuilder = HttpClients.custom();

      //Setting the SSLConnectionSocketFactory
      clientbuilder = clientbuilder.setSSLSocketFactory(sslConSocFactory);

      //Building the CloseableHttpClient
      CloseableHttpClient httpclient = clientbuilder.build();
      
      //Creating the HttpGet request
      HttpGet httpget = new HttpGet("https://example.com/");
 
      //Executing the request
      HttpResponse httpresponse = httpclient.execute(httpget);

      //printing the status line
      System.out.println(httpresponse.getStatusLine());

      //Retrieving the HttpEntity and displaying the no.of bytes read
      HttpEntity entity = httpresponse.getEntity();
      if (entity != null) {
         System.out.println(EntityUtils.toByteArray(entity).length);
      } 
   }
}

输出

在执行时,以上程序生成以下输出。

HTTP/1.1 200 OK
1270