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.
AndroidKeysetManager manager = AndroidKeysetManager.Builder()
.withSharedPref(getApplicationContext(), "my_keyset_name", "my_pref_file_name")
.withKeyTemplate(AesGcmHkfStreamingKeyManager.aes128GcmHkdf4KBTemplate())
.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 an invalid keyset is found, an InvalidKeyException is thrown.
If a keyset is not found, and a KeyTemplate is set with AndroidKeysetManager.Builder.withKeyTemplate(com.google.crypto.tink.KeyTemplate), a fresh keyset
is generated and is written to the my_keyset_name preference of the my_pref_file_name shared preferences file.
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.
If a master key URI is set with AndroidKeysetManager.Builder.withMasterKeyUri(java.lang.String), the
keyset may be encrypted with a key generated and stored in Android Keystore.
Android Keystore is only available on Android M or newer. Since it has been found that Android
Keystore is unreliable on certain devices. Tink runs a self-test to detect such problems and
disables Android Keystore accordingly, even if a master key URI is set. Users can check whether
Android Keystore is in use with isUsingKeystore().
When Android Keystore is disabled or otherwise unavailable, keysets will be stored in cleartext. This is not as bad as it sounds because keysets remain inaccessible to any other apps running on the same device. Moreover, as of July 2020, most active Android devices support either full-disk encryption or file-based encryption, which provide strong security protection against key theft even from attackers with physical access to the device. Android Keystore is only useful when you want to require user authentication for key use, which should be done if and only if you're absolutely sure that Android Keystore is working properly on your target devices.
The master key URI must start with android-keystore://. The remaining of the URI is
used as a key ID when calling Android Keystore. If the master key doesn't exist, a fresh one is
generated. If the master key already exists but is unusable, a KeyStoreException is
thrown.
This class is thread-safe.
| 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 Android Keystore is being used to wrap Tink keysets.
|
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()