How can I get a list of trusted root certificates in Java?
Asked Answered
T

3

39

I would like to be able to get access to all trusted root certificates programmatically in a Java app.

I was looking at the keystore interface, but I'm hoping to get the list of trusted roots that's implicit with the JRE.

Is this accessible anywhere?

Tarazi answered 18/8, 2010 at 0:33 Comment(0)
S
42

There's an example that shows how to get a Set of the root certificates and iterate through them called Listing the Most-Trusted Certificate Authorities (CA) in a Key Store. Here's a slightly modified version that prints out each certificate (tested on Windows Vista).

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.PKIXParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.Iterator;


public class Main {

    public static void main(String[] args) {
        try {
            // Load the JDK's cacerts keystore file
            String filename = System.getProperty("java.home") + "/lib/security/cacerts".replace('/', File.separatorChar);
            FileInputStream is = new FileInputStream(filename);
            KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
            String password = "changeit";
            keystore.load(is, password.toCharArray());

            // This class retrieves the most-trusted CAs from the keystore
            PKIXParameters params = new PKIXParameters(keystore);

            // Get the set of trust anchors, which contain the most-trusted CA certificates
            Iterator it = params.getTrustAnchors().iterator();
            while( it.hasNext() ) {
                TrustAnchor ta = (TrustAnchor)it.next();
                // Get certificate
                X509Certificate cert = ta.getTrustedCert();
                System.out.println(cert);
            }
        } catch (CertificateException e) {
        } catch (KeyStoreException e) {
        } catch (NoSuchAlgorithmException e) {
        } catch (InvalidAlgorithmParameterException e) {
        } catch (IOException e) {
        } 
    }
}
Shue answered 18/8, 2010 at 1:1 Comment(9)
ok, I'll try this out. (time passes) It worked. You know, what's sad is that the password for the default keystore really is 'changeit'. Thanks.Tarazi
You know of a better password for the default keystore?Balmuth
is there a way to change the default password??Adrenaline
@jaime: You can change it using keytool. sslshopper.com/…Shue
This is likely to work most of the time, but is not guaranteed: https://mcmap.net/q/169265/-listing-certificates-in-jvm-trust-storeAromaticity
This code has significant limitations, IMO. For example, if the default truststore is set using system properties (javax.net.ssl.trustStore, javax.net.ssl.trustStorePassword, javax.net.ssl.trustStoreType, etc), then this code will end up loading the wrong trust store. This type of code will also cause issues in environments in which the default truststore has been replaced with something like NSS (for FIPS compliance).Shepperd
@Bill - "This class retrieves the most-trusted CAs from the keystore" - please forgive my ignorance... what does "most-trusted" mean?Cerebro
@Cerebro "most-trusted" in this case just refers to a trust anchor (en.wikipedia.org/wiki/Trust_anchor). In the above example, this would be the trusted CA's, or the authorities that issue/sign the certificates of a site you might visit or URL you might interact with.Marroquin
Exampledepot.com is for sale now (2018). But this link seems fine java2s.com/Tutorial/Java/0490__Security/…Pneumato
S
21

This should be more flexible using the default trust store in the system to get all certificates:

TrustManagerFactory trustManagerFactory =
   TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
List<Certificate> x509Certificates = new ArrayList<>();
trustManagerFactory.init((KeyStore)null);                 
Arrays.asList(trustManagerFactory.getTrustManagers()).stream().forEach(t -> {
                    x509Certificates.addAll(Arrays.asList(((X509TrustManager)t).getAcceptedIssuers()));
                });

```

Supersaturated answered 20/10, 2016 at 14:47 Comment(1)
requires Android NGateshead
S
0

A working example, combining concept from Bill the Lizard and k_o_ answer:

import java.io.FileInputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyStore;
import java.security.cert.X509Certificate;

import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

public class JDKTrustStoreCertListing {

    public static void main(String[] args) throws Exception{
        
        String javaHome=System.getProperty("java.home");
        Path jdkCACertPath=Paths.get(javaHome, "lib", "security", "cacerts");
        
        TrustManagerFactory trustManagerFactory=TrustManagerFactory
                                                    .getInstance(TrustManagerFactory
                                                                    .getDefaultAlgorithm());
        
        FileInputStream fis=new FileInputStream(jdkCACertPath.toFile());
        String keystorePassword="changeit";
        
        KeyStore keyStore=KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(fis, keystorePassword.toCharArray());

        fis.close();
        
        trustManagerFactory.init(keyStore);
        
        TrustManager[] truestManagers=trustManagerFactory.getTrustManagers();
        for(TrustManager t:truestManagers)
            for(X509Certificate c:((X509TrustManager)t).getAcceptedIssuers())
                    System.out.println(c.getIssuerX500Principal());
    
    }//main closing

}//class closing
Striper answered 21/3, 2022 at 6:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.