Apache HttpClient 4.5 How to Get Server Certificates
The following tutorial demonstrates how to obtain the certificates from the resource server using Apache HttpClient 4.5. Certificates are used to secure the connection between the client and server over HTTPS using SSL/TLS. When you need details about the certificate, for example: when does the certificate expire?, who issued the certificate? or etc. You need to read the server certificate. In the following example we explain in detail how you can do this.
Maven dependencies
We use maven to manage our dependencies and are using Apache HttpClient version 4.5. Add the following dependency to your project.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.memorynotfound.apache.httpclient.certificate</groupId>
<artifactId>get-server-certificate</artifactId>
<version>1.0.0-SNAPSHOT</version>
<url>https://memorynotfound.com</url>
<name>httpclient - ${project.artifactId}</name>
<dependencies>
<!-- Apache HttpClient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Get Server Certificate(s)
In the following example we make a request to https://google.com to obtain the server certificates. First we create a HttpResponseInterceptor
which will read the certificates from the SSLSession
if present and add the certificates to the HttpContext
where we can use it later for processing.
Next, we create a custom HttpClient
and add the interceptor using the .addInterceptorLast()
factory method.
Finally, we can make an HttpGet
request to the resource server and obtain the server certificates from the HttpContext
where we previously put them. Now that we have the certificates, we can loop over the collection and print some data to the console.
package com.memorynotfound.httpclient;
import org.apache.http.HttpResponseInterceptor;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.DateUtils;
import org.apache.http.conn.ManagedHttpClientConnection;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpCoreContext;
import javax.net.ssl.SSLSession;
import java.io.IOException;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
/**
* This example demonstrates how to obtain server certificates {@link X509Certificate}.
*/
public class HttpClientGetServerCertificate {
public static final String PEER_CERTIFICATES = "PEER_CERTIFICATES";
public static void main(String... args) throws IOException {
// create http response certificate interceptor
HttpResponseInterceptor certificateInterceptor = (httpResponse, context) -> {
ManagedHttpClientConnection routedConnection = (ManagedHttpClientConnection)context.getAttribute(HttpCoreContext.HTTP_CONNECTION);
SSLSession sslSession = routedConnection.getSSLSession();
if (sslSession != null) {
// get the server certificates from the {@Link SSLSession}
Certificate[] certificates = sslSession.getPeerCertificates();
// add the certificates to the context, where we can later grab it from
context.setAttribute(PEER_CERTIFICATES, certificates);
}
};
// create closable http client and assign the certificate interceptor
CloseableHttpClient httpClient = HttpClients
.custom()
.addInterceptorLast(certificateInterceptor)
.build();
try {
// make HTTP GET request to resource server
HttpGet httpget = new HttpGet("https://google.com");
System.out.println("Executing request " + httpget.getRequestLine());
// create http context where the certificate will be added
HttpContext context = new BasicHttpContext();
httpClient.execute(httpget, context);
// obtain the server certificates from the context
Certificate[] peerCertificates = (Certificate[])context.getAttribute(PEER_CERTIFICATES);
// loop over certificates and print meta-data
for (Certificate certificate : peerCertificates){
X509Certificate real = (X509Certificate) certificate;
System.out.println("----------------------------------------");
System.out.println("Type: " + real.getType());
System.out.println("Signing Algorithm: " + real.getSigAlgName());
System.out.println("IssuerDN Principal: " + real.getIssuerX500Principal());
System.out.println("SubjectDN Principal: " + real.getSubjectX500Principal());
System.out.println("Not After: " + DateUtils.formatDate(real.getNotAfter(), "dd-MM-yyyy"));
System.out.println("Not Before: " + DateUtils.formatDate(real.getNotBefore(), "dd-MM-yyyy"));
}
} finally {
// close httpclient
httpClient.close();
}
}
}
Output
The previous application prints the following messages to the console.
Executing request GET https://google.com HTTP/1.1
----------------------------------------
Type: X.509
Signing Algorithm: SHA256withRSA
Issuer Principal: CN=Google Internet Authority G2, O=Google Inc, C=US
Subject Principal: CN=*.google.be, O=Google Inc, L=Mountain View, ST=California, C=US
IssuerDN: CN=Google Internet Authority G2, O=Google Inc, C=US
Not After: 08-08-2017
Not Before: 16-05-2017
----------------------------------------
Type: X.509
Signing Algorithm: SHA256withRSA
Issuer Principal: CN=GeoTrust Global CA, O=GeoTrust Inc., C=US
Subject Principal: CN=Google Internet Authority G2, O=Google Inc, C=US
IssuerDN: CN=GeoTrust Global CA, O=GeoTrust Inc., C=US
Not After: 31-12-2017
Not Before: 01-04-2015
----------------------------------------
Type: X.509
Signing Algorithm: SHA1withRSA
Issuer Principal: OU=Equifax Secure Certificate Authority, O=Equifax, C=US
Subject Principal: CN=GeoTrust Global CA, O=GeoTrust Inc., C=US
IssuerDN: OU=Equifax Secure Certificate Authority, O=Equifax, C=US
Not After: 21-08-2018
Not Before: 21-05-2002
Thank you so much!