Apache HttpClient - 自定义SSL上下文
使用安全套接字层 (SSL),您可以建立客户端和服务器之间的安全连接。它有助于保护敏感信息,例如信用卡号码、用户名、密码、PIN 码等。
您可以使用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对象、表示需要支持的协议的字符串数组、表示需要支持的密码套件的字符串数组和HostnameVerifier对象传递给其构造函数来创建SSLConnectionSocketFactory对象。
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);
示例
以下示例演示了SSLContext的自定义:
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