Download Certificates from URL – Java Example

Sometimes you want to connect to secure URL and you don’t have certificates available. It’s always long & tedious process to download certificates from browser. I this article we will show you simple way to download certificates and store the same in java keystore.

Below are the steps to download/store the certificates in keystore.

Step 1

Compile the LoadCerts.java

javac LoadCerts.java

Step 2

Run the program. Syntax : java LoadCerts [keystore] [passphrase]

java LoadCerts www.google.com

Note : keystore & passphrase are optional. If you haven’t provide both inputs, program will automatically use default java keystore.

Error: keystore file not found
Info: Loading default keystore…
Info: host : www.google.com
Info: keystore : C:\Program Files (x86)\Java\jre1.8.0_221\lib\security\cacerts
Info: Opening connection to www.google.com:443 …
Info: Initiating SSL handshake…
Info: Certificate is already trusted

Info: Server sent 2 certificate(s): 

1 Subject CN=www.google.com, O=Google LLC, L=Mountain View, ST=California, C=US Issuer CN=GTS CA 1O1, O=Google Trust Services, C=US sha1 90 84 00 d2 a5 f3 89 65 2c 84 42 11 23 19 56 6e 44 f3 a8 c8 md5 c5 f4 09 e5 a9 a4 05 41 9d 6d cd bd ca bd d3 1f 

2 Subject CN=GTS CA 1O1, O=Google Trust Services, C=US Issuer CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R2 sha1 df e2 07 0c 79 e7 ff 36 a9 25 ff a3 27 ff e3 de ec f8 f9 c2 md5 db b2 3c 93 92 36 01 2e 71 d5 f4 4d bc 2a ce a0 

Info: Enter certificate to add to trusted keystore or 'q' to quit: [1]

[press enter]

[ [ Version: V3 Subject: CN=www.google.com, O=Google LLC, L=Mountain View, ST=California, C=US Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11 Key: Sun EC public key, 256 bits public x coord: 101927302814230801756457067785060026806484457178273389320734708485918933184235 public y coord: 81084933681194252824876667758858658520768343833362002813683542893160579082782 parameters: secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7) Validity: [From: Wed Jun 17 20:01:22 IST 2020, To: Wed Sep 09 20:01:22 IST 2020] Issuer: CN=GTS CA 1O1, O=Google Trust Services, C=US SerialNumber: [ fd6f3e24 98c25b1d 08000000 0047f033] Certificate Extensions: 10 [1]: ObjectId: 1.3.6.1.4.1.11129.2.4.2 Criticality=false Extension unknown: DER encoded OCTET string = <...> 

Info: Added certificate to keystore 'C:\Program Files (x86)\Java\jre1.8.0_221\lib\security\cacerts' using alias 'www.google.com-1'

Step 3

Check your keystore for updated certificates using keytool command.

keytool -list -keystore cacerts -storepass changeit

Keytool command output.

Keystore type: jks
Keystore provider: SUN

Your keystore contains 91 entries
verisignclass2g2ca [jdk], Aug 25, 2016, trustedCertEntry,
Certificate fingerprint (SHA1): B3:EA:C4:47:76:C9:C8:1C:EA:F2:9D:95:B6:CC:A0:08:
1B:67:EC:9D
www.google.com-1, Jul 13, 2020, trustedCertEntry,
Certificate fingerprint (SHA1): 90:84:00:D2:A5:F3:89:65:2C:84:42:11:23:19:56:6E:
44:F3:A8:C8
digicertassuredidg3 [jdk], Aug 25, 2016, trustedCertEntry,
Certificate fingerprint (SHA1): F5:17:A2:4F:9A:48:C6:C9:F8:A2:00:26:9F:DC:0F:48:
2C:AB:30:89
verisignuniversalrootca [jdk], Aug 25, 2016, trustedCertEntry,
Certificate fingerprint (SHA1): 36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:
7B:B7:0D:54
digicerttrustedrootg4 [jdk], Aug 25, 2016, trustedCertEntry,
Certificate fingerprint (SHA1): DD:FB:16:CD:49:31:C9:73:A2:03:7D:3F:C8:3A:4D:7D:
77:5D:05:E4
....

Java Program – LoadCerts.java

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;


public class LoadCerts {

	private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();

	public static void main(String[] args) throws Exception {

        String host       = null;
        int    port       = -1;
        String keystore	  = null;
        char[] passphrase = null;
        
        String defaultPassphrase = "changeit";
        
        int numArg = 0;
        int nbArgs = args.length;
        
        boolean invalidArgs = false;
        boolean isQuiet = false;
        
        while (numArg < nbArgs) {
            String arg = args[numArg++];
            
            if (host == null) {  // 1st argument is the "host:port"
                String[] c = arg.split(":");
                host = c[0];
                port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
            }
            else if (keystore == null) {  //  2nd argument is the keystore passphrase
            	keystore = arg;
            }
            else if (passphrase == null) {  //  2nd argument is the keystore passphrase
                passphrase = arg.toCharArray();
            }
            else {
                invalidArgs = true;  // too many args
            }
        }

        if (host == null) {
            invalidArgs = true;
        }

        if (invalidArgs) {
            System.out.println("Usage: java LoadCerts host[:port] [keystore] [passphrase]");
            return;
        }
        
        File file = null;
        if(keystore != null) {
        	file = new File(keystore);
        } else {
        	file = new File("");
        }
        
        if (file.isFile() == false) {
        	System.out.println("Error: keystore file not found");
            char SEP = File.separatorChar;
            File dir = new File(System.getProperty("java.home") + SEP + "lib" + SEP + "security");
            file = new File(dir, "jssecacerts");
            if (file.isFile() == false) {
            	System.out.println("Info: Loading default keystore...");
            	passphrase = defaultPassphrase.toCharArray();
                file = new File(dir, "cacerts");
                keystore = file.getAbsolutePath();
            }
        }
        
        System.out.println("Info: host : "+host);
        System.out.println("Info: keystore : "+keystore);

        //Load keystore
        InputStream in = new FileInputStream(keystore);
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(in, passphrase);
        in.close();
        
        SSLContext context = SSLContext.getInstance("TLS");
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(ks);
        X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0];
        SaveTrustManager tm = new SaveTrustManager(defaultTrustManager);
        context.init(null, new TrustManager[]{tm}, null);
        SSLSocketFactory factory = context.getSocketFactory();

        System.out.println("Info: Opening connection to " + host + ":" + port + " ...");
        
        //Initiate socket
        SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
        socket.setSoTimeout(10000);
        
        try {
            System.out.println("Info: Initiating SSL handshake...");
            socket.startHandshake();
            socket.close();
            System.out.println("Info: Certificate is already trusted");
        } catch (SSLException e) {
            e.printStackTrace(System.out);
        }
        
        X509Certificate[] chain = tm.chain;
        if (chain == null) {
            System.out.println("Error: Could not obtain server certificate chain");
            return;
        }
        
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        System.out.println();
        System.out.println("Info: Server sent " + chain.length + " certificate(s):");
        System.out.println();
        
        MessageDigest sha1 = MessageDigest.getInstance("SHA1");
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        for (int i = 0; i < chain.length; i++) {
            X509Certificate cert = chain[i];
            System.out.println(" " + (i + 1) + " Subject " + cert.getSubjectDN());
            System.out.println("   Issuer  " + cert.getIssuerDN());
            sha1.update(cert.getEncoded());
            System.out.println("   sha1    " + toHexString(sha1.digest()));
            md5.update(cert.getEncoded());
            System.out.println("   md5     " + toHexString(md5.digest()));
            System.out.println();
        }

        int k;
        if (isQuiet) {
            System.out.println("Info: Adding first certificate to trusted keystore");
            k = 0;
        }
        else {
            System.out.println("Info: Enter certificate to add to trusted keystore or 'q' to quit: [1]");
            String line = reader.readLine().trim();
            try {
                k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
            } catch (NumberFormatException e) {
                System.out.println("Error: KeyStore not changed");
                return;
            }
        }

        X509Certificate cert = chain[k];
        String alias = host + "-" + (k + 1);
        ks.setCertificateEntry(alias, cert);

        OutputStream out = new FileOutputStream(keystore);
        ks.store(out, passphrase);
        out.close();

        System.out.println(cert);
        System.out.println("Info: Added certificate to keystore '"+keystore+"' using alias '" + alias + "'");

	}
 
	private static String toHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder(bytes.length * 3);
        for (int b : bytes) {
            b &= 0xff;
            sb.append(HEXDIGITS[b >> 4]);
            sb.append(HEXDIGITS[b & 15]);
            sb.append(' ');
        }
        return sb.toString();
    }
	
	//Inner class to save the default trust manager
	private static class SaveTrustManager implements X509TrustManager {

        private final X509TrustManager tm;
        private X509Certificate[] chain;

        SaveTrustManager(X509TrustManager tm) {
            this.tm = tm;
        }

        public X509Certificate[] getAcceptedIssuers() {
            // This change has been done due to the following resolution advised for Java 1.7+
            // http://infposs.blogspot.kr/2013/06/installcert-and-java-7.html
            return new X509Certificate[0];
            //throw new UnsupportedOperationException();
        }

        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            throw new UnsupportedOperationException();
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            this.chain = chain;
            tm.checkServerTrusted(chain, authType);
        }
    }
}
Design a site like this with WordPress.com
Get started