Class AndroidKeysetManager
- java.lang.Object
-
- com.google.crypto.tink.integration.android.AndroidKeysetManager
-
public final class AndroidKeysetManager extends java.lang.ObjectA wrapper ofKeysetManagerthat supports reading/writingKeysetto/from private shared preferences on Android.We don't recommend using this class. Instead, directly use
AndroidKeystore.Warning
This class reads and writes to shared preferences, thus is best not to run on the UI thread.
Usage
// One-time operations, should be done when the application is starting up. // Instead of repeatedly instantiating these crypto objects, instantiate them once and save for // later use. AndroidKeysetManager manager = AndroidKeysetManager.Builder() .withSharedPref(getApplicationContext(), "my_keyset_name", "my_pref_file_name") .withKeyTemplate(KeyTemplates.get("AES128_GCM_HKDF_4KB")) .build(); StreamingAead streamingAead = manager.getKeysetHandle().getPrimitive(RegistryConfiguration.get(), StreamingAead.class);This will read a keyset stored in the
my_keyset_namepreference of themy_pref_file_namepreferences file. If the preference file name is null, it uses the default preferences file.- If a keyset is found, but cannot be read, either an
IOExceptionor aGeneralSecurityExceptionis thrown. The most common cause is that the master key is missing or the wrong master key is used. In this case, aGeneralSecurityExceptionwould be thrown. This is an irrecoverable error. You'd have to delete the keyset in Shared Preferences and all existing data encrypted with it. - If a keyset is not found, and a
KeyTemplateis set withAndroidKeysetManager.Builder.withKeyTemplate(com.google.crypto.tink.KeyTemplate), a fresh keyset is generated and is written to themy_keyset_namepreference of themy_pref_file_nameshared preferences file.
Adding a new key
The resulting manager supports all operations supported by
KeysetManager. For example to add a key to the keyset, you can do:manager.add(KeyTemplates.get("AES128_GCM_HKDF_4KB"));All operations that manipulate the keyset would automatically persist the new keyset to permanent storage.
Opportunistic keyset encryption with Android Keystore
Warning: because Android Keystore is unreliable, we strongly recommend disabling it by not setting any master key URI.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. You 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, aKeyStoreExceptionis thrown.This class is thread-safe.
- Since:
- 1.0.0
- If a keyset is found, but cannot be read, either an
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classAndroidKeysetManager.BuilderA builder forAndroidKeysetManager.
-
Method Summary
All Methods Instance Methods Concrete Methods Deprecated Methods Modifier and Type Method Description AndroidKeysetManageradd(KeyTemplate keyTemplate)Generates and adds a fresh key generated usingkeyTemplate.AndroidKeysetManageradd(com.google.crypto.tink.proto.KeyTemplate keyTemplate)Generates and adds a fresh key generated usingkeyTemplate.AndroidKeysetManagerdelete(int keyId)Deletes the key withkeyId.AndroidKeysetManagerdestroy(int keyId)Destroys the key material associated with thekeyId.AndroidKeysetManagerdisable(int keyId)Disables the key withkeyId.AndroidKeysetManagerenable(int keyId)Enables the key withkeyId.KeysetHandlegetKeysetHandle()Returns aKeysetHandleof the managed keyset.booleanisUsingKeystore()Returns whether Android Keystore is being used to wrap Tink keysets.AndroidKeysetManagerpromote(int keyId)Deprecated.usesetPrimary(int)AndroidKeysetManagerrotate(com.google.crypto.tink.proto.KeyTemplate keyTemplate)Deprecated.Please useadd(com.google.crypto.tink.proto.KeyTemplate).AndroidKeysetManagersetPrimary(int keyId)Sets the key withkeyIdas primary.
-
-
-
Method Detail
-
getKeysetHandle
public KeysetHandle getKeysetHandle() throws java.security.GeneralSecurityException
Returns aKeysetHandleof the managed keyset.- Throws:
java.security.GeneralSecurityException
-
rotate
@CanIgnoreReturnValue @Deprecated public AndroidKeysetManager rotate(com.google.crypto.tink.proto.KeyTemplate keyTemplate) throws java.security.GeneralSecurityException
Deprecated.Please useadd(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.Generates and adds a fresh key generated usingkeyTemplate, and sets the new key as the primary key.- Throws:
java.security.GeneralSecurityException- if cannot find anyKeyManagerthat can handlekeyTemplate
-
add
@CanIgnoreReturnValue public AndroidKeysetManager add(com.google.crypto.tink.proto.KeyTemplate keyTemplate) throws java.security.GeneralSecurityException
Generates and adds a fresh key generated usingkeyTemplate.- Throws:
java.security.GeneralSecurityException- if cannot find anyKeyManagerthat can handlekeyTemplate
-
add
@CanIgnoreReturnValue public AndroidKeysetManager add(KeyTemplate keyTemplate) throws java.security.GeneralSecurityException
Generates and adds a fresh key generated usingkeyTemplate.- Throws:
java.security.GeneralSecurityException- if cannot find anyKeyManagerthat can handlekeyTemplate
-
setPrimary
@CanIgnoreReturnValue public AndroidKeysetManager setPrimary(int keyId) throws java.security.GeneralSecurityException
Sets the key withkeyIdas primary.- Throws:
java.security.GeneralSecurityException- if the key is not found or not enabled
-
promote
@InlineMe(replacement="this.setPrimary(keyId)") @CanIgnoreReturnValue @Deprecated public AndroidKeysetManager promote(int keyId) throws java.security.GeneralSecurityException
Deprecated.usesetPrimary(int)Sets the key withkeyIdas primary.- Throws:
java.security.GeneralSecurityException- if the key is not found or not enabled
-
enable
@CanIgnoreReturnValue public AndroidKeysetManager enable(int keyId) throws java.security.GeneralSecurityException
Enables the key withkeyId.- Throws:
java.security.GeneralSecurityException- if the key is not found
-
disable
@CanIgnoreReturnValue public AndroidKeysetManager disable(int keyId) throws java.security.GeneralSecurityException
Disables the key withkeyId.- Throws:
java.security.GeneralSecurityException- if the key is not found or it is the primary key
-
delete
@CanIgnoreReturnValue public AndroidKeysetManager delete(int keyId) throws java.security.GeneralSecurityException
Deletes the key withkeyId.- Throws:
java.security.GeneralSecurityException- if the key is not found or it is the primary key
-
destroy
@CanIgnoreReturnValue public AndroidKeysetManager destroy(int keyId) throws java.security.GeneralSecurityException
Destroys the key material associated with thekeyId.- Throws:
java.security.GeneralSecurityException- if the key is not found or it is the primary key
-
isUsingKeystore
public boolean isUsingKeystore()
Returns whether Android Keystore is being used to wrap Tink keysets.
-
-