What key alias need to use in EncryptedSharedPreferences?

11.3k views Asked by At

enter image description here

how can I use key alias in Encrypted sharedprefernces? below is my Encrypted shared preference

KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
                    DEFAULT_MASTER_KEY_ALIAS,
                    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                    .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                    .setKeySize(DEFAULT_AES_GCM_MASTER_KEY_SIZE)
                    .build();

            MasterKey masterKey = new MasterKey.Builder(this)
                    .setKeyGenParameterSpec(spec)
                    .build();

            SharedPreferences sharedPreferences = EncryptedSharedPreferences.create(this,
                    this.getResources().getString(R.string.app_preferences),
                    masterKey,
                    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
                    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
            );

I got below exception when implemented this,

 W/AndroidKeysetManager: keyset not found, will generate a new one
    java.io.FileNotFoundException: can't read keyset; the pref value __androidx_security_crypto_encrypted_prefs_key_keyset__ does not exist
        at com.google.crypto.tink.integration.android.SharedPrefKeysetReader.readPref(SharedPrefKeysetReader.java:71)
        at com.google.crypto.tink.integration.android.SharedPrefKeysetReader.readEncrypted(SharedPrefKeysetReader.java:89)
        at com.google.crypto.tink.KeysetHandle.read(KeysetHandle.java:105)
        at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.read(AndroidKeysetManager.java:311)
        at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.readOrGenerateNewKeyset(AndroidKeysetManager.java:287)
        at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.build(AndroidKeysetManager.java:238)
        at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:155)
        at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:120)

I need to replace DEFAULT_MASTER_KEY_ALIAS with key alias mentioned in that box? If yes, then how can I do that without hardcoding?

I have replaced DEFAULT_MASTER_KEY_ALIAS with key alias mentioned in Project Structure under modules. Got below exception.

java.lang.IllegalArgumentException: KeyGenParamSpec's key alias does not match provided alias (_androidx_security_master_key_ vs mykeyalias
2

There are 2 answers

1
Paulo Henrique Teixeira On

You don't necessarily need to use keyalias in this case. But I couldn't use KeyGenParameterSpec so I used KeyScheme and it worked for me. Try using it:

MasterKey masterKey = new MasterKey.Builder(this)
              .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
              .build();

Instead of:

MasterKey masterKey = new MasterKey.Builder(this)
                .setKeyGenParameterSpec(spec)
                .build();
0
Jorge Mathias On

Your problem comes from this line:

MasterKey masterKey = new MasterKey.Builder(this)

According to the implementation of MasterKey.Builder(), if you don't provide the second parameter that is the key alias

 public Builder(@NonNull Context context, @NonNull String keyAlias) {
        mContext = context.getApplicationContext();
        mKeyAlias = keyAlias;
    }

Then the default key alias is being used

public Builder(@NonNull Context context) {
        this(context, MasterKey.DEFAULT_MASTER_KEY_ALIAS);
    }

So once you try to build with a KeyGenParameterSpec with a different alias, it is complaining. Make use of the constructor with the key alias as second parameter, then it should work.

Sorry being late answering, I've just faced the same problem. I've preferred to share this to help others while looking for an answer.