| page.title=Android Keystore System |
| @jd:body |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| <h2>In this document</h2> |
| <ol> |
| <li><a href="#SecurityFeatures">Security Features</a></li> |
| <li><a href="#WhichShouldIUse">Choosing Between a Keychain or the Android Keystore Provider</a></li> |
| <li><a href="#UsingAndroidKeyStore">Using Android Keystore Provider |
| </a></li> |
| <ol> |
| <li><a href="#GeneratingANewPrivateKey">Generating a New Private Key</a></li> |
| <li><a href="#WorkingWithKeyStoreEntries">Working with Keystore Entries</a></li> |
| <li><a href="#ListingEntries">Listing Entries</a></li> |
| <li><a href="#SigningAndVerifyingData">Signing and Verifying Data</a></li> |
| </ol> |
| </ol> |
| |
| <h2>Blog articles</h2> |
| <ol> |
| <li><a |
| href="http://android-developers.blogspot.com/2012/03/unifying-key-store-access-in-ics.html"> |
| <h4>Unifying Key Store Access in ICS</h4> |
| </a></li> |
| </ol> |
| </div> |
| </div> |
| |
| <p>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. Moreover, it offers facilities to restrict when and |
| how keys can be used, such as requiring user authentication for key use or |
| restricting keys to be used only in certain cryptographic modes. See |
| <a href="#SecurityFeatures">Security Features</a> section for more information.</p> |
| |
| <p>The Keystore system is used by the {@link |
| android.security.KeyChain} API as well as the Android |
| Keystore provider feature that was introduced in Android 4.3 |
| (API level 18). This document goes over when and how to use the |
| Android Keystore provider.</p> |
| |
| |
| <h2 id="SecurityFeatures">Security Features</h2> |
| |
| Android Keystore system protects key material from unauthorized use. Firstly, Android Keystore |
| mitigates unauthorized use of key material outside of the Android device by preventing extraction of |
| the key material from application processes and from the Android device as a whole. Secondly, |
| Android KeyStore mitigates unauthorized use of key material on the Android device by making apps |
| specify authorized uses of their keys and then enforcing these restrictions outside of the apps' |
| processes. |
| |
| <h3 id="ExtractionPrevention">Extraction Prevention</h3> |
| |
| Key material of Android Keystore keys is protected from extraction using two security measures: |
| <ul> |
| <li>Key material never enters the application process. When an application performs cryptographic |
| operations using an Android Keystore key, behind the scenes plaintext, ciphertext, and messages to |
| be signed or verified are fed to a system process which carries out the cryptographic operations. |
| If the app's process is compromised, the attacker may be able to use the app's keys but will not |
| be able to extract their key material (for example, to be used outside of the Android device). |
| </li> |
| <li>Key material may be bound to the secure hardware (e.g., Trusted Execution Environment (TEE), |
| Secure Element (SE)) of the Android device. When this feature is enabled for a key, its key |
| material is never exposed outside of secure hardware. If the Android OS is compromised or an |
| attacker can read the device's internal storage, the attacker may be able to use any app's Android |
| Keystore keys on the Android device, but not extract them from the device. This feature is enabled |
| only if the device's secure hardware supports the particular combination of key algorithm, block |
| modes, padding schemes, and digests with which the key is authorized to be used. To check whether |
| the feature is enabled for a key, obtain a {@link android.security.keystore.KeyInfo} for the key |
| and inspect the return value of |
| {@link android.security.keystore.KeyInfo#isInsideSecureHardware() KeyInfo.isInsideSecurityHardware()}. |
| </li> |
| </ul> |
| |
| <h3 id="KeyUseAuthorizations">Key Use Authorizations</h3> |
| |
| To mitigate unauthorized use of keys on the Android device, Android Keystore lets apps specify |
| authorized uses of their keys when generating or importing the keys. Once a key is generated or |
| imported, its authorizations can not be changed. Authorizations are then enforced by the Android |
| Keystore whenever the key is used. This is an advanced security feature which is generally useful |
| only if your requirements are that a compromise of your application process after key |
| generation/import (but not before or during) cannot lead to unauthorized uses of the key. |
| |
| <p>Supported key use authorizations fall into the following categories: |
| <ul> |
| <li><em>cryptography</em>: authorized key algorithm, operations or purposes (encrypt, decrypt, sign, |
| verify), padding schemes, block modes, digests with which the key can be used;</li> |
| <li><em>temporal validity interval</em>: interval of time during which the key is authorized for |
| use;</li> |
| <li><em>user authentication</em>: the key can only be used if the user has been authenticated |
| recently enough. See <a href="#UserAuthentication">Requiring User Authentication For Key Use</a>. |
| </li> |
| </ul> |
| |
| <p>As an additional security measure, for keys whose key material is inside secure hardware (see |
| {@link android.security.keystore.KeyInfo#isInsideSecureHardware() KeyInfo.isInsideSecurityHardware()}) |
| some key use authorizations may be enforced by secure hardware, depending on the Android device. |
| Cryptographic and user authentication authorizations are likely to be enforced by secure hardware. |
| Temporal validity interval authorizations are unlikely to be enforced by the secure hardware |
| because it normally does not have an independent secure real-time clock. |
| |
| <p>Whether a key's user authentication authorization is enforced by the secure hardware can be |
| queried using |
| {@link android.security.keystore.KeyInfo#isUserAuthenticationRequirementEnforcedBySecureHardware() KeyInfo.isUserAuthenticationRequirementEnforcedBySecureHardware()}. |
| |
| <h2 id="WhichShouldIUse">Choosing Between a Keychain or the |
| Android Keystore Provider</h2> |
| |
| <p>Use the {@link android.security.KeyChain} API when you want |
| system-wide credentials. When an app requests the use of any credential |
| through the {@link android.security.KeyChain} API, users get to |
| choose, through a system-provided UI, which of the installed credentials |
| an app can access. This allows several apps to use the |
| same set of credentials with user consent.</p> |
| |
| <p>Use the Android Keystore provider to let an individual app store its own |
| credentials that only the app itself can access. |
| This provides a way for apps to manage credentials that are usable |
| only by itself while providing the same security benefits that the |
| {@link android.security.KeyChain} API provides for system-wide |
| credentials. This method requires no user interaction to select the credentials.</p> |
| |
| <h2 id="UsingAndroidKeyStore">Using Android Keystore Provider</h2> |
| |
| <p> |
| To use this feature, you use the standard {@link java.security.KeyStore} |
| and {@link java.security.KeyPairGenerator} or |
| {@link javax.crypto.KeyGenerator} classes along with the |
| {@code AndroidKeyStore} provider introduced in Android 4.3 (API level 18).</p> |
| |
| <p>{@code AndroidKeyStore} is registered as a {@link |
| java.security.KeyStore} type for use with the {@link |
| java.security.KeyStore#getInstance(String) KeyStore.getInstance(type)} |
| method and as a provider for use with the {@link |
| java.security.KeyPairGenerator#getInstance(String, String) |
| KeyPairGenerator.getInstance(algorithm, provider)} and {@link |
| javax.crypto.KeyGenerator#getInstance(String, String) |
| KeyGenerator.getInstance(algorithm, provider)} methods.</p> |
| |
| <h3 id="GeneratingANewPrivateKey">Generating a New Private Key</h3> |
| |
| <p>Generating a new {@link java.security.PrivateKey} requires that |
| you also specify the initial X.509 attributes that the self-signed |
| certificate will have. You can replace the certificate at a later |
| time with a certificate signed by a Certificate Authority.</p> |
| |
| <p>To generate the key, use a {@link java.security.KeyPairGenerator} |
| with {@link android.security.KeyPairGeneratorSpec}:</p> |
| |
| {@sample development/samples/ApiDemos/src/com/example/android/apis/security/KeyStoreUsage.java generate} |
| |
| <h3 id="GeneratingANewSecretKey">Generating a New Secret Key</h3> |
| |
| <p>To generate the key, use a {@link javax.crypto.KeyGenerator} with |
| {@link android.security.keystore.KeyGenParameterSpec}. |
| |
| <h3 id="WorkingWithKeyStoreEntries">Working with Keystore Entries</h3> |
| |
| <p>Using the {@code AndroidKeyStore} provider takes place through |
| all the standard {@link java.security.KeyStore} APIs.</p> |
| |
| <h4 id="ListingEntries">Listing Entries</h4> |
| |
| <p>List entries in the keystore by calling the {@link |
| java.security.KeyStore#aliases()} method:</p> |
| |
| {@sample development/samples/ApiDemos/src/com/example/android/apis/security/KeyStoreUsage.java list} |
| |
| <h4 id="SigningAndVerifyingData">Signing and Verifying Data</h4> |
| |
| <p>Sign data by fetching the {@link |
| java.security.KeyStore.Entry} from the keystore and using the |
| {@link java.security.Signature} APIs, such as {@link |
| java.security.Signature#sign()}:</p> |
| |
| {@sample development/samples/ApiDemos/src/com/example/android/apis/security/KeyStoreUsage.java sign} |
| |
| <p>Similarly, verify data with the {@link java.security.Signature#verify(byte[])} method:</p> |
| |
| {@sample development/samples/ApiDemos/src/com/example/android/apis/security/KeyStoreUsage.java verify} |
| |
| <h3 id="UserAuthentication">Requiring User Authentication For Key Use</h3> |
| |
| <p>When generating or importing a key into the {@code AndroidKeyStore} you can specify that the key |
| is only authorized to be used if the user has been authenticated. The user is authenticated using a |
| subset of their secure lock screen credentials (pattern/PIN/password, fingerprint). |
| |
| <p>This is an advanced security feature which is generally useful only if your requirements are that |
| a compromise of your application process after key generation/import (but not before or during) |
| cannot bypass the requirement for the user to be authenticated to use the key. |
| |
| <p>When a key is authorized to be used only if the user has been authenticated, it is configured to |
| operate in one of the two modes: |
| <ul> |
| <li>User authentication authorizes the use of keys for a duration of time. All keys in this mode are |
| authorized for use as soon as the user unlocks the secure lock screen or confirms their secure |
| lock screen credential using the |
| {@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent(CharSequence, CharSequence) KeyguardManager.createConfirmDeviceCredentialIntent} |
| flow. The duration for which the authorization remains valid is specific to each key, as specified |
| using {@code setUserAuthenticationValidityDurationSeconds} during key generation or import. Such |
| keys can only be generated or imported if the secure lock screen is enabled (see |
| {@link android.app.KeyguardManager#isDeviceSecure() KeyguardManager.isDeviceSecure()}). These keys |
| become permanently invalidated once the secure lock screen is disabled (reconfigured to None, |
| Swipe or other mode which does not authenticate the user) or forcibly reset (e.g. by a Device |
| Administrator).</li> |
| <li>User authentication authorizes a specific cryptographic operation associated with one key. In |
| this mode, each operation involving such a key must be individually authorized by the user. |
| Currently, the only means of such authorization is fingerprint authentication: |
| {@link android.hardware.fingerprint.FingerprintManager#authenticate(CryptoObject, CancellationSignal, int, AuthenticationCallback, Handler) FingerprintManager.authenticate}. |
| Such keys can only be generated or imported if at least one fingerprint is enrolled (see |
| {@link android.hardware.fingerprint.FingerprintManager#hasEnrolledFingerprints() FingerprintManager.hasEnrolledFingerprints}). |
| These keys become permanently invalidated once a new fingerprint is enrolled or all fingerprints |
| are unenrolled.</li> |
| </ul> |