Question1:
I'm developing Android app which read private certificate and key from Android key store. Certificate was imported on Android from .p12 file on SD CARD using Settings > security >Install from storage (Credetial storage).
On version 4.0 and higher I can get certificate and key from Android KeyChain. Can I programmatically get this certificate on Android version below 4.0?
I can see certificate and can choose it from WI-FI settings and that's all. I try "BKS" and "PKCS12" stores, but get empty resultset. I can access CA certificate store and get CA certificate data, but that is not what I need.
Answer1:
The key and certificate are encrypted and stored in /data/misc/keystore
. However, since they have been stored by the system, you don't have the permission to access or decrypt them. Additionally, there is no public API for this.
For an application I am developping, I need to be able to install CA and user certificates and private keys without his or hers concent.
I will have full system priviledges, and its fair to assume that the user will have a password before this happens. I will have the x509 if its a CA certificate or the pk12 if its a User certificate + private key file, and also the password if its the USer certificate + private key. I need to do this to be able to set up WPA-EAP wifi configurations automatically, and prefibly I want this to happen without the employees having to notice anything.
If anyone also know how to list all certificates that is installed, I would be very grateful.
I have checked throughout the day, and tested a bit with keystore_cli without success, and I have also read through the CertInstaller code without getting any wiser. Everything there is package-wide so I cannot call the methods directly, + it seems to send stuff further away to com.android.settings", "com.android.settings.CredentialStorage".
Any advice would be very great.
EDIT
For those wondering, here is how I did it with the CA Certificates. The application needs to be able to run as the system user (
android:sharedUserId="android.uid.system"
in android manifest ).
// Android...why do you enjoy doing my life so difficult...
try {
Class<?> keyStoreClass = WifiConfiguration.class.getClassLoader().loadClass("android.security.KeyStore");
Method getInstanceMethod = keyStoreClass.getMethod("getInstance");
Object keyStore = getInstanceMethod.invoke(null);
Log.d("DeviceManager", "Got keystore" + keyStore.toString());
// Put(Key, Value)
Method putCertificateMethod = keyStoreClass.getMethod("put", String.class, byte[].class);
Log.d("DeviceManager", "Putting...");
RandomAccessFile file = new RandomAccessFile("/data/ca.crt", "r");
byte[] b = new byte[(int)file.length()];
file.read(b);
byte[] cacert = b;
Log.d("DeviceManager", "Certificate is bytes long: " + b.length);
putCertificateMethod.invoke(keyStore, "CACERT_name", cacert);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Answer:
Fortunately this is not possible on a stock device. Otherwise, any rogue app will be able to install CA certificates without user consent. If you have small set of devices, you might have to pre-provision them. As for PKCS#12 files, they are password protected so someone will need to enter the password.
Not sure what you mean by 'full system privileges', but if you can link your app with platform code and sign it with the system certificate, you can call KeyChainService methods directly. This will let you install certificates. Additionally, CA certificates are just stored as files, so you can copy them over to the right place. Some details here: http://nelenkov.blogspot.jp/2011/11/ics-credential-storage-implementation.html
|
answered
Jun 22 '12 at 3:26
| |
–
–
–
–
–
|
|