Android Central Keystore
Asked Answered
D

2

9

I'm hoping that there's a way to programmatically access a central trusted keystore on an Android device. I know one exists, at least for verifying SSL connections etc. which also comes with a handy tool for adding certificates, browsing, etc. (Found under settings->location & security->manage trusted certificates)

I'd like to be able to programmatically retrieve public keys from it for the purpose of encrypting files etc.

Given the documentation available, it seems like other app developers are managing their own keystore within their app, which seems redundant.

Any ideas?

Delectation answered 9/8, 2011 at 20:15 Comment(5)
What you would find is server certificates, useful for the purposes you've already outlined. What you would not find -- and not want to add, I would think -- is personal certificates useful for file encryption, your stated purpose.Wormseed
Right they appear to only be CA certs. I'd still be interested in finding out whether or not they can be programatically accessed / modified and also whether another central keystore exists for email certificates etc.Delectation
You can certainly access the trust store and load it, but there is no official API for this. It's a regular Bouncy Castle keystore, you can simply use the KeyStore class.Shivers
BTW, what device/version are you seeing the 'manage trusted certificates' menu on? It is not in the official Android build (at least Gingerbread).Shivers
Thanks Nikolay! I figured that would be the case, I just didnt know what the path was or whether it was even accessible at all by external apps. Regarding what device/version, I'm using an Atrix with the AT&T build of 2.3. I'm surprised to hear that it's not part of the core build. Interesting...Delectation
S
9

This is not supported, may break in future versions, etc., but here's how to get a list of the trusted certificates. You cannot add new ones without root access, because /system is mounted read-only. But if you do have root access, you can use the regular KeyStore API's to add certificates.

KeyStore ks = KeyStore.getInstance("BKS");
InputStream is = new FileInputStream("/etc/security/cacerts.bks");
ks.load(is, "changeit".toCharArray());

List<X509Certificate> certs = new ArrayList<X509Certificate>();
Enumeration<String> aliases = ks.aliases();
while (aliases.hasMoreElements()) {
  String alias = aliases.nextElement();
  X509Certificate cert = (X509Certificate) ks.getCertificate(alias);
  certs.add(cert);
}

EDIT: This should work with needing to hardcode the path to the keystore:

TrustManagerFactory tmf = TrustManagerFactory
                    .getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init((KeyStore) null);
X509TrustManager xtm = (X509TrustManager) tmf.getTrustManagers()[0];
for (X509Certificate cert : xtm.getAcceptedIssuers()) {
    String certStr = "S:" + cert.getSubjectDN().getName() + "\nI:"
                        + cert.getIssuerDN().getName();
    Log.d(TAG, certStr);
}
Shivers answered 10/8, 2011 at 2:31 Comment(3)
And of course it did break...at least on a Motorola XOOM tablet upgraded to 4.x; /etc/security/cacerts.bks was replaced with the directory/etc/security/cacerts/ containing the certs as individual PEM encoded files.Delectation
You can add certificates in ICS via the API. I even wrote about it :) nelenkov.blogspot.com/2011/12/…Shivers
This is showing an error "File not found exception".. what to do for that?Kampala
Y
3

ICS (Android 4.0 / API 14) introduced the TrustedCertificateStore (not directly available in the SDK) that enables you to do exactly that. You can access it using the JCA Keystore api like this:

/**
 * Android Central Keystore repo usually located on /data/misc/keychain 
 * including the system trusted anchors located on /system/etc/security
 */
KeyStore keyStore = KetStore.getInstance("AndroidCAStore");
keyStore.load(null, null); //Load default system keystore
Enumeration<String> keyAliases = keyStore.aliases();

while(keyAliases.hasMoreElements()){
    String alias = keyAliases.nextElement();
    X509Certificate cert = (X509Certificate) keyStore.getCertificate(alias);

    //<User cert in whatever way you want>
}
Yeung answered 11/7, 2015 at 14:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.