Apache HttpClient - 自定义 SSL 上下文
使用安全套接字层,您可以在客户端和服务器之间建立安全连接。 它有助于保护敏感信息,例如信用卡号、用户名、密码、密码等。
您可以通过使用 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 对象的方式,您可以允许所有主机、仅允许自签名证书、仅允许特定协议等。
仅允许特定协议(To allow only particular protocols),通过传递 SSLContext 对象创建 SSLConnectionSocketFactory 对象,表示需要支持的协议的字符串数组,表示需要支持的密码套装的字符串数组,并且 一个 HostnameVerifier 对象到它的构造函数。
new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
允许所有主机(To allow all hosts), 通过传递 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