Certificate pinning for secure connection
In certificate pinning, the client maintains a list of valid certificate fingerprints (or hashes) that are compared against the server’s certificate during the TLS handshake to ensure its authenticity. Below is a simple example in Java that demonstrates how to implement certificate pinning by verifying the fingerprint.
Java Code for Certificate Pinning
This code connects to a server over HTTPS and validates its certificate fingerprint.
import javax.net.ssl.HttpsURLConnection;
import java.io.InputStream;
import java.net.URL;
import java.security.MessageDigest;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Base64;
public class CertificatePinningExample {
// Expected SHA-256 fingerprint of the server certificate (replace with your own)
private static final String EXPECTED_FINGERPRINT = "3A:76:34:F1:2B:9A:4D:E4:AA:62:D3:44:8E:12:5F:77:AF:8F:3A:5A:4D:1F:09:8C:B7:33:91:AA:D7:2B:5C:F3";
public static void main(String[] args) {
String httpsUrl = "https://your-secure-website.com"; // Replace with your server URL
try {
URL url = new URL(httpsUrl);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.connect();
// Get the server certificates
Certificate[] certificates = connection.getServerCertificates();
for (Certificate certificate : certificates) {
if (certificate instanceof X509Certificate) {
X509Certificate x509Cert = (X509Certificate) certificate;
// Compute the SHA-256 fingerprint
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] certEncoded = x509Cert.getEncoded();
byte[] fingerprintBytes = md.digest(certEncoded);
// Format the fingerprint as a colon-separated string
String fingerprint = bytesToHex(fingerprintBytes);
System.out.println("Server Certificate Fingerprint: " + fingerprint);
if (fingerprint.equalsIgnoreCase(EXPECTED_FINGERPRINT)) {
System.out.println("Certificate is trusted!");
} else {
System.out.println("WARNING: Certificate fingerprint mismatch!");
}
break;
}
}
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
private static String bytesToHex(byte[] bytes) {
StringBuilder hexString = new StringBuilder();
for (byte b : bytes) {
hexString.append(String.format("%02X:", b));
}
return hexString.toString().replaceAll(":$", ""); // Remove trailing colon
}
}
Steps to Use
- Replace
https://your-secure-website.com
with the server URL you want to connect to. - Replace
EXPECTED_FINGERPRINT
with your server’s real certificate SHA-256 fingerprint.
How to Get the Certificate Fingerprint
- Visit the website in your browser.
- Click the lock icon near the address bar, then “Certificate.”
- Look for “SHA-256 fingerprint.”