Android documentation about keystore system has a sub-section Choose between a keychain or the Android keystore provider, it says we should use the KeyChain API when we want system-wide credentials. What is a system wide credential? When should I use it? Can you explain it with an example?
Before answering your question I need to ensure that you have basic knowledge of KeyStore and Android keystore system. Therefore, at the beginning, I will be covering some basic overview of these terms in case if you require. After that, I will try to answer your questions.
KeyStore can be defined as a database, API or even a class depending on the context. To make it simple, KeyStore can be defined as a secure collection of aliased keys and certificates. Typically, KeyStores are saved in the file storage, protected with password.
Android keystore system
If we read the official documentation, it says
The Android Keystore system lets you store cryptographic keys in a container to make it more difficult to extract from the device. Once keys are in the keystore, they can be used for cryptographic operations with the key material remaining non-exportable.
So, from the above statement we can infer that, it lets you,
- Store cryptographic keys (private, public keys)
- Perform cryptographic operations using stored keys (encrypt, decrypt, sign, verify, etc.)
Now you might be wondering, where and how it stores those credentials? Actually, it stores the credentials in a system credential storage or KeyStore either by the KeyChain API or by the AndroidKeyStore provider feature. For better understanding, let's know a little bit about their history,
A system KeyStore was introduced in Android 1.6 (Donut). But unfortunately, at that time, apps were not able to access it as it's access was only limited to VPNs and for Wifi authentication. Therefore, apps were maintaining their own KeyStore. It was okay but sometimes it was causing manageability issues when multiple apps were wanting to share common credentials among them. To address this problem, Android 4.0 (ICS) introduced the KeyChain API which allowed apps to access the system KeyStore with user's permission.
With KeyChain API, apps can request user to install or choose credentials by prompting system dialog. It also allows apps to list and access their allowed credentials stored in the system KeyStore. Most interestingly, the apps don't have to use separate password to protect the system keystore as it is protected by lock screen and device administration. The credentials that are imported by any app can be accessed by other apps with the user's permission. You can also see the list of user credentials in the System Settings by navigating to Settings > Security & lock screen > Encryption & credentials > User credentials. (The settings path and menu may vary depending on the device manufacturer and OS version. It is given based on my Oneplus 6. see the Screenshot)
AndroidKeyStore provider feature
This feature was introduced in Android 4.3 (API level 18) to let apps generate, store their credentials in the system keystore which can only be accessed by the app itself. To perform operations, no user interaction is required.
I think I am done with providing sufficient information to move forward with answering your questions. Now let's try to answer your questions,
What is a system-wide credential?
In general, the credentials that are stored using KeyChain API are system-wide credentials. Because they can be used by any other apps within the system if the user permits. On the other hand, credentials stored using AndroidKeyStore provider feature can only be used by the app itself.
When should I use it? Can you explain it with an example?
You should use it when you have multiple apps installed in the same device need to talk to the same server with a common set of shared credentials. For instance, you have an email app and a browser app which talk to the same backend server with the same set of credentials. KeyChain API allows you to use the same credentials that can be used by both the email app and the browser app as they are system-wide credentials. This type of credentials can also be used for VPN, SSL authentication, digital signature and encryption/decryption etc.
I hope now you have a clear understanding of Android Keystore system. I will appreciate any type of corrections as I am not perfect.
To clear up your confusion, I would like to divide Keystore in the following two categories depending on manageability,
- Self-managed Keystore where you are responsible for saving the Keystore in a file or retrieving it from that file, and also generating or importing keys into that Keystore as well. This documentation shows how to implement self-managed Keystore.
- System managed Keystore where the system is responsible for storing or retrieving the Keystore in a file which is accessible by the system only. Android System provides two APIs i.e. KeyChain and Android Keystore provider to access the system managed Keystore. Now let's see the difference between these two APIs,
KeyChain vs Android Keystore provider
- In KeyChain API you need to generate keys by your own and import in through this API. On the other hand, Android Keystore provider lets you both generate and import keys into the system managed Keystore
- The keys imported using KeyChain API is shareable across the system. That's why it's called the system-wide credential. Once an app imports a key in the system Keystore using KeyChain API, not only the app can access the key but also the other apps can access the key using KeyChain API. On the other hand, keys generated or imported using Android Keystore provider are not shareable i.e. the keys can only be accessed the app that generated or imported the keys. As other apps in the system can not access the keys using Android Keystore provider API, they are not considered as system-wide credentials.
I hope the above explanation helps. Let me know if you have further confusion.