Using Secure Socket Layer, you can establish a secured connection between the client and server. It helps to safeguard sensitive information such as credit card numbers, usernames, passwords, pins, etc.
You can make connections more secure by creating your own SSL context using the HttpClient library.
Follow the steps given below to customize SSLContext using HttpClient library −
Step 1 – Create SSLContextBuilder object
SSLContextBuilder is the builder for the SSLContext objects. Create its object using the custom() method of the SSLContexts class.
//Creating SSLContextBuilder object SSLContextBuilder SSLBuilder = SSLContexts.custom();
Step 2 – Load the Keystore
In the path Java_home_directory/jre/lib/security/, you can find a file named cacerts. Save this as your key store file (with extension .jks). Load the keystore file and, its password (which is changeit by default) using the loadTrustMaterial() method of the SSLContextBuilder class.
//Loading the Keystore file File file = new File("mykeystore.jks"); SSLBuilder = SSLBuilder.loadTrustMaterial(file, "changeit".toCharArray());
Step 3 – build an SSLContext object
An SSLContext object represents a secure socket protocol implementation. Build an SSLContext using the build() method.
//Building the SSLContext SSLContext sslContext = SSLBuilder.build();
Step 4 – Creating SSLConnectionSocketFactory object
SSLConnectionSocketFactory is a layered socket factory for TSL and SSL connections. Using this, you can verify the Https server using a list of trusted certificates and authenticate the given Https server.
You can create this in many ways. Depending on the way you create an SSLConnectionSocketFactory object, you can allow all hosts, allow only self-signed certificates, allow only particular protocols, etc.
To allow only particular protocols, create SSLConnectionSocketFactory object by passing an SSLContext object, string array representing the protocols need to be supported, string array representing the cipher suits need to be supported and a HostnameVerifier object to its constructor.
new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
To allow all hosts, create SSLConnectionSocketFactory object by passing a SSLContext object and a NoopHostnameVerifier object.
//Creating SSLConnectionSocketFactory SSLConnectionSocketFactory object SSLConnectionSocketFactory sslConSocFactory = new SSLConnectionSocketFactory(sslcontext, new NoopHostnameVerifier());
Step 5 – Create an HttpClientBuilder object
Create an HttpClientBuilder object using the custom() method of the HttpClients class.
//Creating HttpClientBuilder HttpClientBuilder clientbuilder = HttpClients.custom();
Step 6 – Set the SSLConnectionSocketFactory object
Set the SSLConnectionSocketFactory object to the HttpClientBuilder using the setSSLSocketFactory() method.
//Setting the SSLConnectionSocketFactory clientbuilder = clientbuilder.setSSLSocketFactory(sslConSocFactory);
Step 7 – Build the CloseableHttpClient object
Build the CloseableHttpClient object by calling the build() method.
//Building the CloseableHttpClient CloseableHttpClient httpclient = clientbuilder.build();
Step 8 – Create an HttpGet object
The HttpGet class represents the HTTP GET request which retrieves the information of the given server using a URI.
Create a HTTP GET request by instantiating the HttpGet class by passing a string representing the URI.
//Creating the HttpGet request HttpGet httpget = new HttpGet("https://example.com/");
Step 9 – Execute the request
Execute the request using the execute() method.
//Executing the request HttpResponse httpresponse = httpclient.execute(httpget);
Example
Following example demonstrates the customization of the 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); } } }
Output
On executing, the above program generates the following output.
HTTP/1.1 200 OK 1270