encrypted-datastore icon indicating copy to clipboard operation
encrypted-datastore copied to clipboard

Getting Crash on App Launch

Open parveen-sharma-huru opened this issue 1 year ago • 17 comments

Caused by: java.security.KeyStoreException: the master key android-keystore://_androidx_security_master_key_ exists but is unusable
	at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.readOrGenerateNewMasterKey(AndroidKeysetManager.java:276)
	at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.build(AndroidKeysetManager.java:237)
	at androidx.security.crypto.EncryptedFile$Builder.build(EncryptedFile.java:172)
	at com.huru.datastore.di.DataStoreModule$getDataStore$1.invoke(DataStoreModule.kt:61)
	at com.huru.datastore.di.DataStoreModule$getDataStore$1.invoke(DataStoreModule.kt:55)
	at io.github.osipxd.security.crypto.EncryptedPreferenceDataStoreFactoryKt.createEncrypted(EncryptedPreferenceDataStoreFactory.kt:61)
	at io.github.osipxd.security.crypto.EncryptedPreferenceDataStoreFactoryKt.createEncrypted$default(EncryptedPreferenceDataStoreFactory.kt:48)

parveen-sharma-huru avatar Mar 19 '24 10:03 parveen-sharma-huru

@praveenathuru, thank you for the report. Is it full stacktrace? Are there more causes?

osipxd avatar Mar 19 '24 11:03 osipxd

Not sure just got this one today as I launched my app after 24 hours on Android 9. I'm maintaining 2 different Data Stores variants in the application one for User and one for App level configuration. This is how I'm maintaining data stores.

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class AppDataStore

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class UserDataStore

@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class UserDataStoreManager

@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class AppDataStoreManager

@Module
@InstallIn(SingletonComponent::class)
object DataStoreModule {
    @Provides
    @Singleton
    @UserDataStore
    fun provideUserDataPreference(@ApplicationContext context: Context): DataStore<Preferences> {
        return context.getDataStore(fileName = "user_data.preferences_pb")
    }

    @Provides
    @Singleton
    @AppDataStore
    fun provideAppDataPreference(@ApplicationContext context: Context): DataStore<Preferences> {
        return context.getDataStore(fileName = "app_data.preferences_pb")
    }

    private fun Context.getDataStore(fileName: String): DataStore<Preferences> {
        return PreferenceDataStoreFactory.createEncrypted {
            EncryptedFile.Builder(
                dataStoreFile(fileName = fileName),
                this,
                MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
                EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
            ).build()
        }
    }

    @Provides
    @Singleton
    @UserDataStoreManager
    fun provideUserDataStoreManager(@UserDataStore dataStore: DataStore<Preferences>): DataStoreManager {
        return DataStoreManagerImpl(dataStore)
    }

    @Provides
    @Singleton
    @AppDataStoreManager
    fun provideAppDataStoreManager(@AppDataStore dataStore: DataStore<Preferences>): DataStoreManager {
        return DataStoreManagerImpl(dataStore)
    }
}

parveen-sharma-huru avatar Mar 19 '24 11:03 parveen-sharma-huru

There are many reasons why the library can't decrypt master key, but firstly I'd suggest updating tink (the cryptographic library used under the hood) to the latest version:

dependencies {
    implementation("com.google.crypto.tink:tink-android:1.12.0")
}

If it does not help, look at this issue: https://github.com/tink-crypto/tink/issues/535 (especially this comment and this one) Similar issue in Google's issuetracker: b/176215143

osipxd avatar Mar 19 '24 11:03 osipxd

@osipxd any luck with this crash? we are facing crashes heavily in the production because of this. Any workaround you suggest? Did you updated the tink under the hood in this library?

parveen-sharma-huru avatar Jul 17 '24 05:07 parveen-sharma-huru

@praveenathuru, yes, I've updated Tink to the latest version in v1.0.0. Do you have fresh stack traces with an updated version?

osipxd avatar Jul 17 '24 11:07 osipxd

@osipxd We are using 1.0.0-beta01 version since long, now planning to upgrade it to v1.0.0. Hope v1.1.1-beta03 is not required at this point of time.

parveen-sharma-huru avatar Jul 17 '24 11:07 parveen-sharma-huru

Hope v1.1.1-beta03 is not required at this point of time.

It is required only if you want to use datastore 1.1.0.

osipxd avatar Jul 17 '24 17:07 osipxd

@praveenathuru, have you had a chance to check if the problem persists on the new version?

osipxd avatar Sep 10 '24 14:09 osipxd

@osipxd I'm having the same crash but only on a galaxy a35 so far. Using version 1.1.1-beta03.

itamarb-ramm avatar Sep 18 '24 10:09 itamarb-ramm

@osipxd I'm having the same crash but only on a galaxy a35 so far. Using version 1.1.1-beta03.

Could you tell me what versions of Android are affected?

osipxd avatar Sep 18 '24 10:09 osipxd

Android 14. Seems to run fine on A53 also with Android 14.

itamarb-ramm avatar Sep 18 '24 10:09 itamarb-ramm

Sorry @osipxd. It seems I am having a different issue:

Caused by javax.crypto.AEADBadTagException:
       at android.security.keystore2.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:632)
       at javax.crypto.Cipher.doFinal(Cipher.java:2132)
       at com.google.crypto.tink.integration.android.AndroidKeystoreAesGcm.decryptInternal(AndroidKeystoreAesGcm.java:110)
       at com.google.crypto.tink.integration.android.AndroidKeystoreAesGcm.decrypt(AndroidKeystoreAesGcm.java:93)
       at com.google.crypto.tink.KeysetHandle.decrypt(KeysetHandle.java:937)
       at com.google.crypto.tink.KeysetHandle.readWithAssociatedData(KeysetHandle.java:822)
       at com.google.crypto.tink.KeysetHandle.read(KeysetHandle.java:803)
       at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.readMasterkeyDecryptAndParseKeyset(AndroidKeysetManager.java:383)
       at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.build(AndroidKeysetManager.java:303)
       at androidx.security.crypto.EncryptedFile$Builder.build(EncryptedFile.java:172)
       at io.github.osipxd.security.crypto.EncryptedDataStoreSingletonDelegate$getValue$1$1.invoke(EncryptedDataStoreDelegate.kt:128)
       at io.github.osipxd.security.crypto.EncryptedDataStoreSingletonDelegate$getValue$1$1.invoke(EncryptedDataStoreDelegate.kt:116)
       at io.github.osipxd.security.crypto.EncryptedDataStoreFactoryKt.createEncrypted(EncryptedDataStoreFactory.kt:78)
       at io.github.osipxd.security.crypto.EncryptedDataStoreSingletonDelegate.getValue(EncryptedDataStoreDelegate.kt:116)
       at io.github.osipxd.security.crypto.EncryptedDataStoreSingletonDelegate.getValue(EncryptedDataStoreDelegate.kt:89)

itamarb-ramm avatar Sep 18 '24 12:09 itamarb-ramm