Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get server certificate chain then verify it's valid and trusted in Java

Tags:

I need to create an Https connection with a remote server then retrieve and verify the certificate.

I have established the connection fine:

try {  
    url = new URL(this.SERVER_URL);  
    HttpURLConnection con = (HttpURLConnection) url.openConnection();   
    HttpsURLConnection secured = (HttpsURLConnection) con;  
    secured.connect(); 
}  

But it seems getServerCertificateChain() method is undefined by the type HttpsURLConnection.

So how do I retrieve the server certificate chain? My understanding is that getServerCertificateChain() should return an array of X509Certificate objects and that this class has methods I can use to interrogate the certificate.

I need to verify that:

  1. the certificate is valid and trusted,
  2. check the Certificate Revocation List Distribution Point against the certificate serial number
  3. make sure it isn't expired and
  4. check that the URL in the certificate is matches another (which I already have retrieved ).

I'm lost and would really appreciate any help!

like image 322
Marc H Avatar asked Aug 26 '11 01:08

Marc H


2 Answers

The method you want is getServerCertificates, not getServerCertificateChain. There is some nice sample code here.


EDIT

Added some sample code of my own. Good starting point for you. Don't forget to look at the Javadocs for HttpsURLConnection and X509Certificate.

import java.net.URL;
import java.security.cert.Certificate;
import java.security.cert.CertificateExpiredException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HttpsURLConnection;

public class TestSecuredConnection {

    /**
     * @param args
     */
    public static void main(String[] args) {
        TestSecuredConnection tester = new TestSecuredConnection();
        try {
            tester.testConnectionTo("https://www.google.com");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public TestSecuredConnection() {
        super();
    }

    public void testConnectionTo(String aURL) throws Exception {
        URL destinationURL = new URL(aURL);
        HttpsURLConnection conn = (HttpsURLConnection) destinationURL
                .openConnection();
        conn.connect();
        Certificate[] certs = conn.getServerCertificates();
        for (Certificate cert : certs) {
            System.out.println("Certificate is: " + cert);
            if(cert instanceof X509Certificate) {
                try {
                    ( (X509Certificate) cert).checkValidity();
                    System.out.println("Certificate is active for current date");
                } catch(CertificateExpiredException cee) {
                    System.out.println("Certificate is expired");
                }
            }
        }
    }
}
like image 194
Perception Avatar answered Sep 28 '22 16:09

Perception


Quick googling brought me to this example using BouncyCastle. I think it better answers the question. http://www.nakov.com/blog/2009/12/01/x509-certificate-validation-in-java-build-and-verify-chain-and-verify-clr-with-bouncy-castle/

like image 45
Kirby Avatar answered Sep 28 '22 15:09

Kirby