KeyChain
public
final
class
KeyChain
extends Object
java.lang.Object | |
↳ | android.security.KeyChain |
The KeyChain
class provides access to private keys and
their corresponding certificate chains in credential storage.
Applications accessing the KeyChain
normally go through
these steps:
- Receive a callback from an
X509KeyManager
that a private key is requested. - Call
choosePrivateKeyAlias
to allow the user to select from a list of currently available private keys and corresponding certificate chains. The chosen alias will be returned by the callbackKeyChainAliasCallback#alias
, or null if no private key is available or the user cancels the request. - Call
getPrivateKey(Context, String)
andgetCertificateChain(Context, String)
to retrieve the credentials to return to the correspondingX509KeyManager
callbacks.
An application may remember the value of a selected alias to
avoid prompting the user with choosePrivateKeyAlias
on subsequent connections. If the alias is
no longer valid, null will be returned on lookups using that value
An application can request the installation of private keys and
certificates via the Intent
provided by createInstallIntent()
. Private keys installed via this Intent
will be accessible via choosePrivateKeyAlias(Activity, KeyChainAliasCallback, String, Principal, Uri, String)
while
Certificate Authority (CA) certificates will be trusted by all
applications through the default X509TrustManager
.
Summary
Constants | |
---|---|
String |
ACTION_KEYCHAIN_CHANGED
Broadcast Action: Indicates the contents of the keychain has changed. |
String |
ACTION_KEY_ACCESS_CHANGED
Broadcast Action: Indicates that the access permissions for a private key have changed. |
String |
ACTION_STORAGE_CHANGED
This constant was deprecated
in API level 26.
Use |
String |
ACTION_TRUST_STORE_CHANGED
Broadcast Action: Indicates the contents of the trusted certificate store has changed. |
String |
EXTRA_CERTIFICATE
Optional extra to specify an X.509 certificate to install on
the |
String |
EXTRA_KEY_ACCESSIBLE
Used as a boolean extra field in |
String |
EXTRA_KEY_ALIAS
Used as a String extra field in |
String |
EXTRA_NAME
Optional extra to specify a |
String |
EXTRA_PKCS12
Optional extra for use with the |
String |
KEY_ALIAS_SELECTION_DENIED
Used by DPC or delegated app in
|
Public constructors | |
---|---|
KeyChain()
|
Public methods | |
---|---|
static
void
|
choosePrivateKeyAlias(Activity activity, KeyChainAliasCallback response, String[] keyTypes, Principal[] issuers, String host, int port, String alias)
Launches an |
static
void
|
choosePrivateKeyAlias(Activity activity, KeyChainAliasCallback response, String[] keyTypes, Principal[] issuers, Uri uri, String alias)
Launches an |
static
Intent
|
createInstallIntent()
Returns an |
static
Intent
|
createManageCredentialsIntent(AppUriAuthenticationPolicy policy)
Returns an |
static
X509Certificate[]
|
getCertificateChain(Context context, String alias)
Returns the |
static
AppUriAuthenticationPolicy
|
getCredentialManagementAppPolicy(Context context)
Called by the credential management app to get the authentication policy
|
static
PrivateKey
|
getPrivateKey(Context context, String alias)
Returns the |
static
boolean
|
isBoundKeyAlgorithm(String algorithm)
This method was deprecated
in API level 23.
Whether the key is bound to the secure hardware is known only
once the key has been imported. To find out, use:
|
static
boolean
|
isCredentialManagementApp(Context context)
Check whether the caller is the credential management app |
static
boolean
|
isKeyAlgorithmSupported(String algorithm)
Returns |
static
boolean
|
removeCredentialManagementApp(Context context)
Called by the credential management app |
Inherited methods | |
---|---|
Constants
ACTION_KEYCHAIN_CHANGED
public static final String ACTION_KEYCHAIN_CHANGED
Broadcast Action: Indicates the contents of the keychain has changed. Sent when a KeyChain entry is added, modified or removed.
Constant Value: "android.security.action.KEYCHAIN_CHANGED"
ACTION_KEY_ACCESS_CHANGED
public static final String ACTION_KEY_ACCESS_CHANGED
Broadcast Action: Indicates that the access permissions for a private key have changed.
Constant Value: "android.security.action.KEY_ACCESS_CHANGED"
ACTION_STORAGE_CHANGED
public static final String ACTION_STORAGE_CHANGED
This constant was deprecated
in API level 26.
Use ACTION_KEYCHAIN_CHANGED
, ACTION_TRUST_STORE_CHANGED
or
ACTION_KEY_ACCESS_CHANGED
. Apps that target a version higher than
Build.VERSION_CODES.N_MR1
will only receive this broadcast if they
register for it at runtime.
Broadcast Action: Indicates the trusted storage has changed. Sent when one of this happens:
- a new CA is added,
- an existing CA is removed or disabled,
- a disabled CA is enabled,
- trusted storage is reset (all user certs are cleared),
- when permission to access a private key is changed.
Constant Value: "android.security.STORAGE_CHANGED"
ACTION_TRUST_STORE_CHANGED
public static final String ACTION_TRUST_STORE_CHANGED
Broadcast Action: Indicates the contents of the trusted certificate store has changed. Sent when one the following occurs:
- A pre-installed CA is disabled or re-enabled
- A CA is added or removed from the trust store
Constant Value: "android.security.action.TRUST_STORE_CHANGED"
EXTRA_CERTIFICATE
public static final String EXTRA_CERTIFICATE
Optional extra to specify an X.509 certificate to install on
the Intent
returned by createInstallIntent()
.
The extra value should be a PEM or ASN.1 DER encoded byte[]
. An X509Certificate
can be converted to DER
encoded bytes with X509Certificate#getEncoded
.
EXTRA_NAME
may be used to provide a default alias
name for the installed certificate.
Constant Value: "CERT"
EXTRA_KEY_ACCESSIBLE
public static final String EXTRA_KEY_ACCESSIBLE
Used as a boolean extra field in ACTION_KEY_ACCESS_CHANGED
to supply if the key is
accessible to the application.
Constant Value: "android.security.extra.KEY_ACCESSIBLE"
EXTRA_KEY_ALIAS
public static final String EXTRA_KEY_ALIAS
Used as a String extra field in ACTION_KEY_ACCESS_CHANGED
to supply the alias of
the key.
Constant Value: "android.security.extra.KEY_ALIAS"
EXTRA_NAME
public static final String EXTRA_NAME
Optional extra to specify a String
credential name on
the Intent
returned by createInstallIntent()
.
Constant Value: "name"
EXTRA_PKCS12
public static final String EXTRA_PKCS12
Optional extra for use with the Intent
returned by
createInstallIntent()
to specify a PKCS#12 key store to
install. The extra value should be a byte[]
. The bytes
may come from an external source or be generated with KeyStore.store(OutputStream, char)
on a "PKCS12" instance.
The user will be prompted for the password to load the key store.
The key store will be scanned for KeyStore.PrivateKeyEntry
entries and both the
private key and associated certificate chain will be installed.
EXTRA_NAME
may be used to provide a default alias
name for the installed credentials.
Constant Value: "PKCS12"
KEY_ALIAS_SELECTION_DENIED
public static final String KEY_ALIAS_SELECTION_DENIED
Used by DPC or delegated app in
DeviceAdminReceiver.onChoosePrivateKeyAlias(Context, Intent, int, Uri, String)
or
DelegatedAdminReceiver.onChoosePrivateKeyAlias(Context, Intent, int, Uri, String)
to identify that
the requesting app is not granted access to any key, and nor will the user be able to grant
access manually.
Constant Value: "android:alias-selection-denied"
Public constructors
KeyChain
public KeyChain ()
Public methods
choosePrivateKeyAlias
public static void choosePrivateKeyAlias (Activity activity, KeyChainAliasCallback response, String[] keyTypes, Principal[] issuers, String host, int port, String alias)
Launches an Activity
for the user to select the alias
for a private key and certificate pair for authentication. The
selected alias or null will be returned via the
KeyChainAliasCallback callback.
A device policy controller (as a device or profile owner) can
intercept the request before the activity is shown, to pick a
specific private key alias by implementing
onChoosePrivateKeyAlias
.
keyTypes
and issuers
may be used to
narrow down suggested choices to the user. If either keyTypes
or issuers
is specified and non-empty, and there are no
matching certificates in the KeyChain, then the certificate
selection prompt would be suppressed entirely.
host
and port
may be used to give the user
more context about the server requesting the credentials.
alias
allows the caller to preselect an existing
alias which will still be subject to user confirmation.
Parameters | |
---|---|
activity |
Activity : The Activity context to use for
launching the new sub-Activity to prompt the user to select
a private key; used only to call startActivity(); must not
be null. |
response |
KeyChainAliasCallback : Callback to invoke when the request completes;
must not be null. |
keyTypes |
String : The acceptable types of asymmetric keys such as
"RSA", "EC" or null.
Value is KeyProperties.KEY_ALGORITHM_RSA , KeyProperties.KEY_ALGORITHM_EC , android.security.keystore.KeyProperties.KEY_ALGORITHM_XDH, KeyProperties.KEY_ALGORITHM_AES , KeyProperties.KEY_ALGORITHM_HMAC_SHA1 , KeyProperties.KEY_ALGORITHM_HMAC_SHA224 , KeyProperties.KEY_ALGORITHM_HMAC_SHA256 , KeyProperties.KEY_ALGORITHM_HMAC_SHA384 , or KeyProperties.KEY_ALGORITHM_HMAC_SHA512 |
issuers |
Principal : The acceptable certificate issuers for the
certificate matching the private key, or null. |
host |
String : The host name of the server requesting the
certificate, or null if unavailable. |
port |
int : The port number of the server requesting the
certificate, or -1 if unavailable. |
alias |
String : The alias to preselect if available, or null if
unavailable. |
choosePrivateKeyAlias
public static void choosePrivateKeyAlias (Activity activity, KeyChainAliasCallback response, String[] keyTypes, Principal[] issuers, Uri uri, String alias)
Launches an Activity
for the user to select the alias
for a private key and certificate pair for authentication. The
selected alias or null will be returned via the
KeyChainAliasCallback callback.
A device policy controller (as a device or profile owner) can
intercept the request before the activity is shown, to pick a
specific private key alias by implementing
onChoosePrivateKeyAlias
.
keyTypes
and issuers
may be used to
narrow down suggested choices to the user. If either keyTypes
or issuers
is specified and non-empty, and there are no
matching certificates in the KeyChain, then the certificate
selection prompt would be suppressed entirely.
uri
may be used to give the user more context about
the server requesting the credentials.
alias
allows the caller to preselect an existing
alias which will still be subject to user confirmation.
Parameters | |
---|---|
activity |
Activity : The Activity context to use for
launching the new sub-Activity to prompt the user to select
a private key; used only to call startActivity(); must not
be null. |
response |
KeyChainAliasCallback : Callback to invoke when the request completes;
must not be null. |
keyTypes |
String : The acceptable types of asymmetric keys such as
"RSA", "EC" or null.
Value is KeyProperties.KEY_ALGORITHM_RSA , KeyProperties.KEY_ALGORITHM_EC , android.security.keystore.KeyProperties.KEY_ALGORITHM_XDH, KeyProperties.KEY_ALGORITHM_AES , KeyProperties.KEY_ALGORITHM_HMAC_SHA1 , KeyProperties.KEY_ALGORITHM_HMAC_SHA224 , KeyProperties.KEY_ALGORITHM_HMAC_SHA256 , KeyProperties.KEY_ALGORITHM_HMAC_SHA384 , or KeyProperties.KEY_ALGORITHM_HMAC_SHA512 |
issuers |
Principal : The acceptable certificate issuers for the
certificate matching the private key, or null. |
uri |
Uri : The full URI the server is requesting the certificate
for, or null if unavailable. |
alias |
String : The alias to preselect if available, or null if
unavailable. |
Throws | |
---|---|
IllegalArgumentException |
if the specified issuers are not
of type X500Principal . |
createInstallIntent
public static Intent createInstallIntent ()
Returns an Intent
that can be used for credential
installation. The intent may be used without any extras, in
which case the user will be able to install credentials from
their own source.
Alternatively, EXTRA_CERTIFICATE
or EXTRA_PKCS12
maybe used to specify the bytes of an X.509
certificate or a PKCS#12 key store for installation. These
extras may be combined with EXTRA_NAME
to provide a
default alias name for credentials being installed.
When used with Activity#startActivityForResult
,
Activity#RESULT_OK
will be returned if a credential was
successfully installed, otherwise Activity.RESULT_CANCELED
will be returned.
Starting from Build.VERSION_CODES.R
, the intent returned by this
method cannot be used for installing CA certificates. Since CA certificates can only be
installed via Settings, the app should provide the user with a file containing the
CA certificate. One way to do this would be to use the MediaStore
API to write the certificate to the MediaStore.Downloads
collection.
Returns | |
---|---|
Intent |
This value cannot be null . |
createManageCredentialsIntent
public static Intent createManageCredentialsIntent (AppUriAuthenticationPolicy policy)
Returns an Intent
that should be used by an app to request to manage the user's
credentials. This is limited to unmanaged devices. The authentication policy must be
provided to be able to make this request successfully.
This intent should be started using Activity#startActivityForResult(Intent, int)
to verify whether the request was successful and whether the user accepted or denied the
request. If the user successfully receives and accepts the request, the result code will be
Activity#RESULT_OK
, otherwise the result code will be
Activity#RESULT_CANCELED
.
KeyChain#isCredentialManagementApp(Context)
should be used to determine whether
an app is already the credential management app.
Parameters | |
---|---|
policy |
AppUriAuthenticationPolicy : The authentication policy determines which alias for a private key and
certificate pair should be used for authentication.
This value cannot be null . |
Returns | |
---|---|
Intent |
This value cannot be null . |
getCertificateChain
public static X509Certificate[] getCertificateChain (Context context, String alias)
Returns the X509Certificate
chain for the requested alias, or null if the alias
does not exist or the caller has no permission to access it (see note on exceptions
in getPrivateKey(Context, String)
).
Note: If a certificate chain was explicitly specified when the alias was installed, this method will return that chain. If only the client certificate was specified at the installation time, this method will try to build a certificate chain using all available trust anchors (preinstalled and user-added).
This method may block while waiting for a connection to another process, and must never be called from the main thread.
As Activity
and Service
contexts are short-lived and can be destroyed
at any time from the main thread, it is safer to rely on a long-lived context such as one
returned from Context#getApplicationContext()
.
In case the caller specifies an alias for which it lacks a grant, it must call
choosePrivateKeyAlias(Activity, KeyChainAliasCallback, String, Principal, Uri, String)
again. See getPrivateKey(Context, String)
for more details on
coping with this scenario.
This method may take several seconds to complete, so it should
only be called from a worker thread.
Parameters | |
---|---|
context |
Context : This value cannot be null . |
alias |
String : The alias of the desired certificate chain, typically
returned via KeyChainAliasCallback#alias .
This value cannot be null . |
Returns | |
---|---|
X509Certificate[] |
Throws | |
---|---|
KeyChainException |
if the alias was valid but there was some problem accessing it. |
IllegalStateException |
if called from the main thread. |
InterruptedException |
getCredentialManagementAppPolicy
public static AppUriAuthenticationPolicy getCredentialManagementAppPolicy (Context context)
Called by the credential management app to get the authentication policy
AppUriAuthenticationPolicy
.
This method may take several seconds to complete, so it should
only be called from a worker thread.
Parameters | |
---|---|
context |
Context : This value cannot be null . |
Returns | |
---|---|
AppUriAuthenticationPolicy |
the credential management app's authentication policy.
This value cannot be null . |
Throws | |
---|---|
SecurityException |
if the caller is not the credential management app. |
getPrivateKey
public static PrivateKey getPrivateKey (Context context, String alias)
Returns the PrivateKey
for the requested alias, or null if the alias does not exist
or the caller has no permission to access it (see note on exceptions below).
This method may block while waiting for a connection to another process, and must never be called from the main thread.
As Activity
and Service
contexts are short-lived and can be destroyed
at any time from the main thread, it is safer to rely on a long-lived context such as one
returned from Context#getApplicationContext()
.
If the caller provides a valid alias to which it was not granted access, then the
caller must invoke choosePrivateKeyAlias(Activity, KeyChainAliasCallback, String, Principal, Uri, String)
again to get another valid alias
or a grant to access the same alias.
On Android versions prior to Q, when a key associated with the specified alias is
unavailable, the method will throw a KeyChainException
rather than return null.
If the exception's cause (as obtained by calling KeyChainException.getCause()
)
is a throwable of type IllegalStateException
then the caller lacks a grant
to access the key and certificates associated with this alias.
This method may take several seconds to complete, so it should
only be called from a worker thread.
Parameters | |
---|---|
context |
Context : This value cannot be null . |
alias |
String : The alias of the desired private key, typically returned via
KeyChainAliasCallback#alias .
This value cannot be null . |
Returns | |
---|---|
PrivateKey |
Throws | |
---|---|
KeyChainException |
if the alias was valid but there was some problem accessing it. |
IllegalStateException |
if called from the main thread. |
InterruptedException |
isBoundKeyAlgorithm
public static boolean isBoundKeyAlgorithm (String algorithm)
This method was deprecated
in API level 23.
Whether the key is bound to the secure hardware is known only
once the key has been imported. To find out, use:
PrivateKey key = ...; // private key from KeyChain
KeyFactory keyFactory =
KeyFactory.getInstance(key.getAlgorithm(), "AndroidKeyStore");
KeyInfo keyInfo = keyFactory.getKeySpec(key, KeyInfo.class);
if (keyInfo.isInsideSecureHardware()) {
// The key is bound to the secure hardware of this Android
}
Returns true
if the current device's KeyChain
binds any
PrivateKey
of the given algorithm
to the device once
imported or generated. This can be used to tell if there is special
hardware support that can be used to bind keys to the device in a way
that makes it non-exportable.
Parameters | |
---|---|
algorithm |
String : This value cannot be null .
Value is KeyProperties.KEY_ALGORITHM_RSA , KeyProperties.KEY_ALGORITHM_EC , android.security.keystore.KeyProperties.KEY_ALGORITHM_XDH, KeyProperties.KEY_ALGORITHM_AES , KeyProperties.KEY_ALGORITHM_HMAC_SHA1 , KeyProperties.KEY_ALGORITHM_HMAC_SHA224 , KeyProperties.KEY_ALGORITHM_HMAC_SHA256 , KeyProperties.KEY_ALGORITHM_HMAC_SHA384 , or KeyProperties.KEY_ALGORITHM_HMAC_SHA512 |
Returns | |
---|---|
boolean |
isCredentialManagementApp
public static boolean isCredentialManagementApp (Context context)
Check whether the caller is the credential management app CredentialManagementApp
.
The credential management app has the ability to manage the user's KeyChain credentials
on unmanaged devices.
KeyChain#createManageCredentialsIntent
should be used by an app to request to
become the credential management app. The user must approve this request before the app can
manage the user's credentials. There can only be one credential management on the device.
This method may take several seconds to complete, so it should
only be called from a worker thread.
Parameters | |
---|---|
context |
Context : This value cannot be null . |
Returns | |
---|---|
boolean |
true if the caller is the credential management app. |
isKeyAlgorithmSupported
public static boolean isKeyAlgorithmSupported (String algorithm)
Returns true
if the current device's KeyChain
supports a
specific PrivateKey
type indicated by algorithm
(e.g.,
"RSA").
Parameters | |
---|---|
algorithm |
String : This value cannot be null .
Value is KeyProperties.KEY_ALGORITHM_RSA , KeyProperties.KEY_ALGORITHM_EC , android.security.keystore.KeyProperties.KEY_ALGORITHM_XDH, KeyProperties.KEY_ALGORITHM_AES , KeyProperties.KEY_ALGORITHM_HMAC_SHA1 , KeyProperties.KEY_ALGORITHM_HMAC_SHA224 , KeyProperties.KEY_ALGORITHM_HMAC_SHA256 , KeyProperties.KEY_ALGORITHM_HMAC_SHA384 , or KeyProperties.KEY_ALGORITHM_HMAC_SHA512 |
Returns | |
---|---|
boolean |
removeCredentialManagementApp
public static boolean removeCredentialManagementApp (Context context)
Called by the credential management app CredentialManagementApp
to unregister as
the credential management app and stop managing the user's credentials.
All credentials previously installed by the credential management app will be removed from the user's device.
An app holding MANAGE_CREDENTIAL_MANAGEMENT_APP
permission can also call this
method to remove the current credential management app, even if it's not the current
credential management app itself.
This method may take several seconds to complete, so it should
only be called from a worker thread.
Parameters | |
---|---|
context |
Context : This value cannot be null . |
Returns | |
---|---|
boolean |
true if the credential management app was successfully removed. |