HTTP Certificate Pinning
Certificate pinning code for Java
package org.example;
import javax.net.ssl.*;
import java.io.*;
import java.net.URL;
import java.security.MessageDigest;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Base64;
public class CertificatePinningClient {
// SHA-256 fingerprint of the expected certificate
// You need to replace this with the actual certificate fingerprint of madhur.co.in
private static final String EXPECTED_CERT_SHA256 = "YOUR_CERT_FINGERPRINT_HERE";
public static void main(String[] args) {
try {
String fingerprint = getCertificateFingerprint("https://localhost:8443");
System.out.println(fingerprint);
// String response = makeSecureRequest("https://madhur.co.in");
// System.out.println("Response: " + response);
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
public static String makeSecureRequest(String urlString) throws Exception {
URL url = new URL(urlString);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
// Set up custom SSL context with certificate pinning
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{new PinningTrustManager()}, null);
connection.setSSLSocketFactory(sslContext.getSocketFactory());
// Set request properties
connection.setRequestMethod("GET");
connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);
// Make the request
connection.getResponseCode();
// Read the response
StringBuilder response = new StringBuilder();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(connection.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
response.append(line).append("\n");
}
}
connection.disconnect();
return response.toString();
}
// Custom TrustManager that implements certificate pinning
private static class PinningTrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
// Not used for client certificates in this example
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws java.security.cert.CertificateException {
if (chain == null || chain.length == 0) {
throw new java.security.cert.CertificateException("Certificate chain is empty");
}
// Get the server certificate (first in chain)
X509Certificate serverCert = chain[0];
try {
// Calculate SHA-256 fingerprint of the certificate
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] certBytes = serverCert.getEncoded();
byte[] fingerprint = md.digest(certBytes);
String certFingerprint = Base64.getEncoder().encodeToString(fingerprint);
System.out.println("Server certificate fingerprint: " + certFingerprint);
System.out.println("Expected fingerprint: " + EXPECTED_CERT_SHA256);
// Check if the certificate matches our pinned certificate
if (!EXPECTED_CERT_SHA256.equals(certFingerprint)) {
throw new java.security.cert.CertificateException("Certificate pinning failed! " +
"Expected: " + EXPECTED_CERT_SHA256 +
", Got: " + certFingerprint);
}
System.out.println("Certificate pinning validation passed!");
} catch (Exception e) {
throw new java.security.cert.CertificateException("Error validating certificate: " + e.getMessage(), e);
}
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
// Utility method to get certificate fingerprint for a given URL
// Run this first to get the actual certificate fingerprint
public static String getCertificateFingerprint(String urlString) throws Exception {
URL url = new URL(urlString);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.connect();
Certificate[] certificates = connection.getServerCertificates();
if (certificates.length > 0) {
X509Certificate cert = (X509Certificate) certificates[0];
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] fingerprint = md.digest(cert.getEncoded());
return Base64.getEncoder().encodeToString(fingerprint);
}
connection.disconnect();
throw new Exception("No certificates found");
}
}