I'm using 'androidx.security:security-crypto:1.1.0-alpha02' in an android project. It works fine for file encryption/decription. I've set up a master key inside the hardware keystore that requires authentication to be used.
private static MasterKey getOrCreateMasterKey(final Application application)
throws IOException, GeneralSecurityException {
return new MasterKey.Builder(application)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.setUserAuthenticationRequired(true, 3600)
.setRequestStrongBoxBacked(true)
.build();
}
The Security API automatically generated what i think is a Tink keyset file, adapted for Android Shared Preferences.
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="__androidx_security_crypto_encrypted_file_keyset__">129c0157ebfb4adffbd04e3ad4cd44336c5e89c3fe455d949031436c63789092960d8b93053de8e1fd855b61047a1d496ff26006958982e6a90f950746dbc7afc6b252bf51149b8404e5ff8616f9911ad54e153bf2c2c21eb571ca11223c77edd01b488465f7ab286ffd9054d7e396d1b2a187152dd9bf76ee5df9a5faefd5e5b7ec159fa04a860f9d237f833763f6c42acbcdedfb06a575264f948049b3841a4f08c094920612480a3d747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e41657347636d486b646653747265616d696e674b6579100118c09492062003</string>
</map>
If I understand correctly, that is the actual DEK used for encrypting the files.
Now the problem is that if I want to export an encrypted file I would not be able to decrypt on another device, because the master key inside the Hardware KeyStore is not exportable.
The best solution would be to export the DEK inside the keyset, with PBKDF2 and decrypt it into another device keyset.
An optional solution would be to create the master key material outside the keystore, protect it with another KeyStore key and export it with PBKDF2 when needed. This will break the logical flow of the jetpack Security library.
I've tried to import the Tink library 'com.google.crypto.tink:tink-android:1.5.0' so that I could start managing the Keyset directly, since the Security API doesn't have implementation for this usecase.
AndroidKeysetManager manager = new AndroidKeysetManager.Builder()
.withSharedPref(getApplicationContext(), "my_keyset_name", "my_pref_file_name")
.withKeyTemplate(AesGcmKeyManager.aes256GcmTemplate())
.withMasterKeyUri(masterKeyUri)
.build();
Anyway, I couldn't find a way to decrypt the key inside the keyset with this manager, in order to be able to encrypt it with a password and export it properly.
Do you know how should face this problem?