public final class AndroidKeysetManager extends Object
KeysetManager that supports reading/writing Keyset to/from private shared preferences on Android.
This class reads and writes to shared preferences, thus is best not to run on the UI thread.
String masterKeyUri = "android-keystore://my_master_key_id";
AndroidKeysetManager manager = AndroidKeysetManager.Builder()
.withSharedPref(getApplicationContext(), "my_keyset_name", "my_pref_file_name")
.withKeyTemplate(AesGcmHkfStreamingKeyManager.aes128GcmHkdf4KBTemplate())
.withMasterKeyUri(masterKeyUri)
.build();
StreamingAead streamingAead = manager.getKeysetHandle().getPrimitive(StreamingAead.class);
This will read a keyset stored in the my_keyset_name preference of the my_pref_file_name preferences file. If the preference file name is null, it uses the default
preferences file.
If the keyset is not found or invalid, and a valid KeyTemplate is set with AndroidKeysetManager.Builder.withKeyTemplate(com.google.crypto.tink.proto.KeyTemplate), a fresh keyset is generated and is written to the
my_keyset_name preference of the my_pref_file_name shared preferences file.
On Android M or newer and if a master key URI is set with AndroidKeysetManager.Builder.withMasterKeyUri(java.lang.String), the keyset is encrypted with a master key
generated and stored in Android Keystore. When
Tink cannot decrypt the keyset it would assume that it is not encrypted.
The master key URI must start with android-keystore://. If the master key doesn't
exist, a fresh one is generated.
Usage of Android Keystore can be disabled with AndroidKeysetManager.Builder.doNotUseKeystore(). Android Keystore on certain devices is broken.
Tink runs a self-test to detect such problems and disable Android Keystore accordingly. Users can
check whether Android Keystore is in use with isUsingKeystore().
On Android L or older, or when either Android Keystore is disabled or the master key URI is not set, the keyset will be stored in cleartext in private preferences which, thanks to the security of the Android framework, no other apps can read or write.
The resulting manager supports all operations supported by KeysetManager. For example
to rotate the keyset, one can do:
manager.rotate(AesGcmHkfStreamingKeyManager.aes128GcmHkdf1MBTemplate());
All operations that manipulate the keyset would automatically persist the new keyset to permanent storage.
| Modifier and Type | Class and Description |
|---|---|
static class |
AndroidKeysetManager.Builder
A builder for
AndroidKeysetManager. |
| Modifier and Type | Method and Description |
|---|---|
AndroidKeysetManager |
add(com.google.crypto.tink.proto.KeyTemplate keyTemplate)
Deprecated.
This method takes a KeyTemplate proto, which is an internal implementation detail.
Please use the add method that takes a
KeyTemplate POJO. |
AndroidKeysetManager |
add(KeyTemplate keyTemplate)
Generates and adds a fresh key generated using
keyTemplate. |
AndroidKeysetManager |
delete(int keyId)
Deletes the key with
keyId. |
AndroidKeysetManager |
destroy(int keyId)
Destroys the key material associated with the
keyId. |
AndroidKeysetManager |
disable(int keyId)
Disables the key with
keyId. |
AndroidKeysetManager |
enable(int keyId)
Enables the key with
keyId. |
KeysetHandle |
getKeysetHandle() |
boolean |
isUsingKeystore()
Returns whether this keyset manager is wrapping keys with Android Keystore.
|
AndroidKeysetManager |
promote(int keyId)
Deprecated.
use
setPrimary |
AndroidKeysetManager |
rotate(com.google.crypto.tink.proto.KeyTemplate keyTemplate)
Deprecated.
Please use
add(com.google.crypto.tink.proto.KeyTemplate). This method adds a new key and immediately promotes it to
primary. However, when you do keyset rotation, you almost never want to make the new key
primary, because old binaries don't know the new key yet. |
AndroidKeysetManager |
setPrimary(int keyId)
Sets the key with
keyId as primary. |
public KeysetHandle getKeysetHandle() throws GeneralSecurityException
KeysetHandle of the managed keysetGeneralSecurityException@Deprecated public AndroidKeysetManager rotate(com.google.crypto.tink.proto.KeyTemplate keyTemplate) throws GeneralSecurityException
add(com.google.crypto.tink.proto.KeyTemplate). This method adds a new key and immediately promotes it to
primary. However, when you do keyset rotation, you almost never want to make the new key
primary, because old binaries don't know the new key yet.keyTemplate, and sets the new key as the
primary key.GeneralSecurityException - if cannot find any KeyManager that can handle keyTemplate@Deprecated public AndroidKeysetManager add(com.google.crypto.tink.proto.KeyTemplate keyTemplate) throws GeneralSecurityException
KeyTemplate POJO.keyTemplate.GeneralSecurityException - if cannot find any KeyManager that can handle keyTemplatepublic AndroidKeysetManager add(KeyTemplate keyTemplate) throws GeneralSecurityException
keyTemplate.GeneralSecurityException - if cannot find any KeyManager that can handle keyTemplatepublic AndroidKeysetManager setPrimary(int keyId) throws GeneralSecurityException
keyId as primary.GeneralSecurityException - if the key is not found or not enabled@Deprecated public AndroidKeysetManager promote(int keyId) throws GeneralSecurityException
setPrimarykeyId as primary.GeneralSecurityException - if the key is not found or not enabledpublic AndroidKeysetManager enable(int keyId) throws GeneralSecurityException
keyId.GeneralSecurityException - if the key is not foundpublic AndroidKeysetManager disable(int keyId) throws GeneralSecurityException
keyId.GeneralSecurityException - if the key is not found or it is the primary keypublic AndroidKeysetManager delete(int keyId) throws GeneralSecurityException
keyId.GeneralSecurityException - if the key is not found or it is the primary keypublic AndroidKeysetManager destroy(int keyId) throws GeneralSecurityException
keyId.GeneralSecurityException - if the key is not found or it is the primary keypublic boolean isUsingKeystore()