How I get a certificate list installed in Android

2020-07-24 04:54发布

问题:

The android.security.KeyChain#getCertificateChain needs an alias. But I want to get all installed X509Certificate.

回答1:

You can use something like this to list trusted certificates. Not exactly documented though, so it might break in future versions.

KeyStore ks = KeyStore.getInstance("AndroidCAStore");
ks.load(null, null);
Enumeration aliases = ks.aliases();
while (aliases.hasMoreElements()) {
    String alias = aliases.nextElement();
    X509Certificate cert = (X509Certificate) 
       ks.getCertificate(alias);
    Log.d(TAG, "Subject DN: " + 
       cert.getSubjectDN().getName());
    Log.d(TAG, "Subject SN: " + 
       cert.getSerialNumber().toString());
    Log.d(TAG, "Issuer DN: " + 
       cert.getIssuerDN().getName());
}


回答2:

List the available certs:

public void PrintInstalledCertificates( ){

    try 
    {
        KeyStore ks = KeyStore.getInstance("AndroidCAStore");
        if (ks != null) 
        {
            ks.load(null, null);
            Enumeration<String> aliases = ks.aliases();
            while (aliases.hasMoreElements()) 
            {
                String alias = (String) aliases.nextElement();
                java.security.cert.X509Certificate cert = (java.security.cert.X509Certificate) ks.getCertificate(alias);

                //To print System Certs only
                if(cert.getIssuerDN().getName().contains(“system”))
                {
                    System.out.println(cert.getIssuerDN().getName());
                }

                //To print User Certs only 
                if(cert.getIssuerDN().getName().contains(“user”))
                {
                    System.out.println(cert.getIssuerDN().getName());
                }

                //To print all certs
                System.out.println(cert.getIssuerDN().getName());                           
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    } catch (KeyStoreException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (java.security.cert.CertificateException e) {
        e.printStackTrace();
    }               
}

Check if a certificate is already installed:

public boolean checkCACertificateInstalled(javax.security.cert.X509Certificate x509){

    boolean isCACertificateInstalled = false;

    try 
    {
        String name = x509.getIssuerDN().getName(); 
        KeyStore ks = KeyStore.getInstance("AndroidCAStore");
        if (ks != null) 
        {
            ks.load(null, null);
            Enumeration<String> aliases = ks.aliases();
            while (aliases.hasMoreElements()) 
            {
                String alias = (String) aliases.nextElement();
                java.security.cert.X509Certificate cert = (java.security.cert.X509Certificate) ks.getCertificate(alias);

                if (cert.getIssuerDN().getName().contains(name)) 
                {
                    isCACertificateInstalled = true;
                    break;
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    } catch (KeyStoreException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (java.security.cert.CertificateException e) {
        e.printStackTrace();
    }

    return isCACertificateInstalled;
}


回答3:

You cannot - android.security.KeyChain doesn't have any methods to retrieve all aliases, and more importantly - not even the service it communicates with (an implementation of the IKeyChainService AIDL interface in the KeyChain app) exposes a method to list all the aliases - thus the grants and keystore are internal to that app.