aws-amplify / amplify-android

The fastest and easiest way to use AWS from your Android app.
https://docs.amplify.aws/lib/q/platform/android/
Apache License 2.0
250 stars 118 forks source link

javax.crypto.AEADBadTagException and android.security.KeyStoreException #2723

Closed sayasheng closed 7 months ago

sayasheng commented 9 months ago

Before opening, please confirm:

Language and Async Model

Java

Amplify Categories

GraphQL API

Gradle script dependencies

```groovy // Put output below this line api "amplifyframework:core:$amplify" api "amplifyframework:aws-auth-cognito:2.4.11" api "amplifyframework:aws-api-appsync:2.4.11" api "amplifyframework:aws-api:2.4.11" ```

Environment information

``` # Put output below this line ------------------------------------------------------------ Gradle 7.5 ------------------------------------------------------------ Build time: 2022-07-14 12:48:15 UTC Revision: c7db7b958189ad2b0c1472b6fe663e6d654a5103 Kotlin: 1.6.21 Groovy: 3.0.10 Ant: Apache Ant(TM) version 1.10.11 compiled on July 10 2021 JVM: 11.0.8-internal (Oracle Corporation 11.0.8-internal+0-adhoc..jdk11u) OS: Windows 10 10.0 amd64 ```

Please include any relevant guides or documentation you're referencing

No response

Describe the bug

02-20 14:36:40.059 E/AndroidRuntime( 4405): java.security.KeyStoreException: the master key android-keystore://amplify_master_key exists but is unusable 02-20 14:36:40.059 E/AndroidRuntime( 4405): at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.readOrGenerateNewMasterKey(AndroidKeysetManager.java:275) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.build(AndroidKeysetManager.java:236) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:123) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at com.amplifyframework.core.store.EncryptedKeyValueRepository.getSharedPreferencesOrThrow(EncryptedKeyValueRepository.kt:110) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at com.amplifyframework.core.store.EncryptedKeyValueRepository.openKeystoreWithAmplifyMasterKey(EncryptedKeyValueRepository.kt:86) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at com.amplifyframework.core.store.EncryptedKeyValueRepository.getOrCreateSharedPreferences(EncryptedKeyValueRepository.kt:64) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at com.amplifyframework.core.store.EncryptedKeyValueRepository.access$getOrCreateSharedPreferences(EncryptedKeyValueRepository.kt:32) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at com.amplifyframework.core.store.EncryptedKeyValueRepository$sharedPreferences$2.invoke(EncryptedKeyValueRepository.kt:48) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at com.amplifyframework.core.store.EncryptedKeyValueRepository$sharedPreferences$2.invoke(EncryptedKeyValueRepository.kt:48) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at com.amplifyframework.core.store.EncryptedKeyValueRepository.getSharedPreferences(EncryptedKeyValueRepository.kt:48) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at com.amplifyframework.core.store.EncryptedKeyValueRepository.get(EncryptedKeyValueRepository.kt:51) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at com.amplifyframework.auth.cognito.data.AWSCognitoAuthCredentialStore.retrieveCredential(AWSCognitoAuthCredentialStore.kt:63) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at com.amplifyframework.auth.cognito.actions.CredentialStoreCognitoActions$loadCredentialStoreAction$$inlined$invoke$1.execute(Action.kt:70) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at com.amplifyframework.statemachine.ConcurrentEffectExecutor$execute$1$1.invokeSuspend(ConcurrentEffectExecutor.kt:26) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684) 02-20 14:36:40.059 E/AndroidRuntime( 4405): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@13a33af, Dispatchers.Default] 02-20 14:36:40.059 E/AndroidRuntime( 4405): Caused by: javax.crypto.AEADBadTagException 02-20 14:36:40.059 E/AndroidRuntime( 4405): at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:517) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:531) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at javax.crypto.Cipher.doFinal(Cipher.java:2267) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at com.google.crypto.tink.integration.android.AndroidKeystoreAesGcm.encryptInternal(AndroidKeystoreAesGcm.java:87) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at com.google.crypto.tink.integration.android.AndroidKeystoreAesGcm.encrypt(AndroidKeystoreAesGcm.java:72) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at com.google.crypto.tink.integration.android.AndroidKeystoreKmsClient.validateAead(AndroidKeystoreKmsClient.java:248) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at com.google.crypto.tink.integration.android.AndroidKeystoreKmsClient.getAead(AndroidKeystoreKmsClient.java:165) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.readOrGenerateNewMasterKey(AndroidKeysetManager.java:267) 02-20 14:36:40.059 E/AndroidRuntime( 4405): ... 20 more 02-20 14:36:40.059 E/AndroidRuntime( 4405): Caused by: android.security.KeyStoreException: Signature/MAC verification failed 02-20 14:36:40.059 E/AndroidRuntime( 4405): at android.security.KeyStore.getKeyStoreException(KeyStore.java:1303) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at android.security.keystore.KeyStoreCryptoOperationChunkedStreamer.doFinal(KeyStoreCryptoOperationChunkedStreamer.java:224) 02-20 14:36:40.059 E/AndroidRuntime( 4405): at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:506)

Reproduction steps (if applicable)

upgrade v1 to v2 and get this issue.

Code Snippet

// Put your code below this line.

Log output

``` // Put your logs below this line ```

amplifyconfiguration.json

No response

GraphQL Schema

```graphql // Put your schema below this line ```

Additional information and screenshots

No response

ankpshah commented 9 months ago

Hello, @sayasheng. can you upgrade to latest version of Amplify v2.14.11? Latest release has fix for adding fallback logic for corrupt keys to EncryptedKeyValueRepository.

sayasheng commented 9 months ago

@ankpshah Yes, I already upgraded to Amplify v2.14.11 from v1 yesterday. This issue still happens on v2.14.11 after clearing all data.

ankpshah commented 9 months ago

Hello @sayasheng, I tried replicating this issue by signing in using v1 (v1.38.8) then upgraded to v2 (v2.14.11). Followed by Sign out and Sign In operation using v2. I was able to sign in without any exceptions or keyStore error.

Here are some questions I have:

  1. Is there any specific step to replicate this?
  2. What kind of Auth configuration are you using?
  3. Which device and API level are you using?
  4. Also in issue description under gradle dependencies I see the version as 2.4.11 just want to make sure you are using the latest version of Amplify.
tylerjroach commented 9 months ago

@sayasheng If you have any specific test devices where you can replicate this issue, I would be curious if you are able to use EncryptedSharedPreferences at all on these devices: https://developer.android.com/reference/androidx/security/crypto/EncryptedSharedPreferences.

It is possible that we are running into a limited set of devices where EncryptedSharedPreferences library does not work properly. This class is critical to securely storing information on the device and we cannot operate without it.

Let us know if this is an edge case you are seeing in the wild, or if you have a test device youi can replicate this with.

sayasheng commented 9 months ago

Hello @sayasheng, I tried replicating this issue by signing in using v1 (v1.38.8) then upgraded to v2 (v2.14.11). Followed by Sign out and Sign In operation using v2. I was able to sign in without any exceptions or keyStore error.

Here are some questions I have:

  1. Is there any specific step to replicate this? @ankpshah Here is my step Step 1 : use amplify version 1.37.4 and sign in a user Step 2: sign out the user Step 3: use amplify version 2.14.11 and use the same user to login
    I got error message "An unclassified error prevented this operation" in this step, however the user can be signed in successfully. image Step 4: sign out the user I got KeyStoreException/AEADBadTagException in this step.

  2. What kind of Auth configuration are you using?

image

  1. Which device and API level are you using? Our device is customize hardware with Android 10. compileSdkVersion is 33.

  2. Also in issue description under gradle dependencies I see the version as 2.4.11 just want to make sure you are using the latest version of Amplify. yes, I am pretty sure that apk is complied with 2.4.11 because apk compiled with 1.37.4 works fine. image

tylerjroach commented 9 months ago

@sayasheng Since you mentioned custom hardware, I'm a bit concerned the devices have a non-standard implementation of the Android KeyStore.

Amplify v2 uses the latest official release of EncryptedSharedPrefrences provided directly from Google. This is a best practice for securely encrypting data on the device.

The logs shown indicate that the device attempted to use the apps default master key, but failed. We then tried to create a fallback master key, which is also failing. If the device is unable to use EncryptedSharedPreferences, Amplify v2 will not function properly. Amplify v1 is not failing because it uses its own encryption methods and does not use EncryptedSharedPreferences.

joon-won commented 7 months ago

Closing this issue due to inactivity. Please feel free to open a new issue if required, thank you

github-actions[bot] commented 7 months ago

This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one.

Uma1r commented 6 months ago

I had this issue popup in one of our apps as well, seemed to be limited to 1 specific device but I am curious as to what the path forward maybe as Google seems to have deprecated Jetpack security crypto library. @tylerjroach

https://android-review.googlesource.com/c/platform/frameworks/support/+/2761067

https://developer.android.com/privacy-and-security/cryptography#jetpack_security_crypto_library

tylerjroach commented 6 months ago

@Uma1r We will determine our best past forward away from EncryptedSharedPreferences and internally handle the data migration when it is time to change. While no new updates are being made to EncryptedSharedPreferences, functionality would not immediately break on current versions of Android. It will continue to be used until we have an alternative ready.

tallaltop7 commented 5 months ago

This issue still persists, is there any update ?