aws-amplify / aws-sdk-android

AWS SDK for Android. For more information, see our web site:
https://docs.amplify.aws
Other
1.03k stars 549 forks source link

Error in retrieving the encryption key used for secure storage of credentials #937

Closed iam1492 closed 5 years ago

iam1492 commented 5 years ago

Describe the bug Upgrade to 2.13.3 make app crash.

To Reproduce A code sample or steps: I use dagger2 to inject s3client. Below is my code in AmazonModule(dagger module) to initialize CognitoCachingCredentialsProvider.

val provider = CognitoCachingCredentialsProvider(activity, BuildConfig.COGNITO_POOL_ID, Regions.AP_NORTHEAST_2)

Which AWS service(s) are affected? App crash

Expected behavior Non crash

Screenshots App crash

Environment Information (please complete the following information):

Additional context I added the call stack of my crash

Caused by java.lang.IllegalArgumentException: key == null
       at javax.crypto.spec.SecretKeySpec.(SecretKeySpec.java:59)
       at com.amazonaws.internal.keyvaluestore.KeyProvider18.getKey(KeyProvider18.java:80)
       at com.amazonaws.internal.keyvaluestore.AWSKeyValueStore.setPersistenceEnabled(AWSKeyValueStore.java:138)
       at com.amazonaws.internal.keyvaluestore.AWSKeyValueStore.(SourceFile:1138)
       at com.amazonaws.auth.CognitoCachingCredentialsProvider.initialize(CognitoCachingCredentialsProvider.java:425)
       at com.amazonaws.auth.CognitoCachingCredentialsProvider.(SourceFile:1425)
       at com.towneers.www.di.modules.AmazonModule.provideCognitoCachingCredentialsProvider$android_50004_realRelease(AmazonModule.java:24)
       at com.towneers.www.di.modules.AmazonModule_ProvideCognitoCachingCredentialsProvider$android_50004_realReleaseFactory.proxyProvideCognitoCachingCredentialsProvider$android_50004_realRelease$53f6d157(AmazonModule_ProvideCognitoCachingCredentialsProvider.java:40)
       at com.towneers.www.di.components.DaggerHoianComponent.getCognitoCachingCredentialsProvider(DaggerHoianComponent.java:1309)
       at com.towneers.www.di.components.DaggerHoianComponent.access$26500(DaggerHoianComponent.java:652)
       at com.towneers.www.di.components.DaggerHoianComponent$PostArticleActivitySubcomponentImpl.injectPostArticleActivity(DaggerHoianComponent.java:6864)
       at com.towneers.www.di.components.DaggerHoianComponent$PostArticleActivitySubcomponentImpl.inject(DaggerHoianComponent.java:6841)
       at com.towneers.www.di.components.DaggerHoianComponent$PostArticleActivitySubcomponentImpl.inject(DaggerHoianComponent.java:6786)
       at dagger.android.DispatchingAndroidInjector.maybeInject(DispatchingAndroidInjector.java:113)
       at dagger.android.DispatchingAndroidInjector.inject(DispatchingAndroidInjector.java:134)
       at dagger.android.AndroidInjection.inject(AndroidInjection.java:59)
       at dagger.android.support.DaggerAppCompatActivity.onCreate(DaggerAppCompatActivity.java:43)
       at com.towneers.www.base.BaseActivity.onCreate(BaseActivity.java:124)
       at com.towneers.www.ui.activity.PostArticleActivity.onCreate(PostArticleActivity.java:135)
       at android.app.Activity.performCreate(Activity.java:5580)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2400)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2495)
       at android.app.ActivityThread.access$900(ActivityThread.java:170)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1304)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:146)
       at android.app.ActivityThread.main(ActivityThread.java:5635)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:515)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
       at dalvik.system.NativeStart.main(NativeStart.java)
mutablealligator commented 5 years ago

@iam1492 Is this the very first run of the app after upgrading to 2.13.3? What version of the SDK did you upgrade from?

This issue occurs when the SDK is not able to load the key from the KeyStore. The key from the KeyStore is used to securely store the information persisted by the CognitoCachingCredentialsProvider.

iam1492 commented 5 years ago

Old version was 2.9.0. And now I downgrade to 2.11.1 to solve this issue. (I cannot go back to 2.9.0 again because of aws database downgrade issue- from 6 to 5) As I know, 2.9.0 does not have KeyStore but anyway crash should not happen.

yong0726 commented 5 years ago

same issue. always crash in Android 4 and 5.

ygnessin commented 5 years ago

We are also seeing this crash in production after we upgraded our AWS SDKs from 2.13.1 to 2.13.3. Our android app uses the kinesis, congitoauth, and cognitoidentityprovider SDKs. The stacktrace is almost identical to the one posted but I'd be happy to share it if that is helpful.

Thanks for these wonderful libraries, and I hope we can have this fixed soon!

mutablealligator commented 5 years ago

@ygnessin @yong0726 @iam1492 Can you see a log statement where the encryption key is successfully generated and stored in the KeyStore? This will help us find if the key generation succeeded in the first place or not.

ygnessin commented 5 years ago

@kvasukib these crashes are occurring in production, so we cannot see any log statements such as the ones you are requesting because our app doesn't log in production. I am not able to repro them locally, unfortunately.

Are you able to estimate how soon a fix for this can be ready? If it is still unknown, we may want to roll back to 2.13.1 until it is fixed.

Thanks!

ygnessin commented 5 years ago

@kvasukib I will however add that this crash appears to be occurring on app startup. So it seems very unlikely that key generation had previously succeeded during the app's lifecycle.

yoavgray commented 5 years ago

@kvasukib to add some context to what @ygnessin wrote, we started seeing crashes in production when we upgraded our AWS SDK from 2.12.5 to 2.13.1, so we will probably downgrade further if this issue won't be resolved soon. Thanks for taking a look.

ygnessin commented 5 years ago

@kvasukib I'm not sure if this is related or represents a separate issue altogether, but in addition to the KeyProvider18 error we are also seeing another crash coming from KeyProvider23. Here is a sample stack trace:

Caused by android.security.KeyStoreException: Key blob corrupted
       at android.security.KeyStore.getKeyStoreException(KeyStore.java:1092)
       at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreSecretKeyFromKeystore(AndroidKeyStoreProvider.java:283)
       at android.security.keystore.AndroidKeyStoreSpi.engineGetKey(AndroidKeyStoreSpi.java:98)
       at java.security.KeyStore.getKey(KeyStore.java:825)
       at com.amazonaws.internal.keyvaluestore.KeyProvider23.getKey(KeyProvider23.java:65)
       at com.amazonaws.internal.keyvaluestore.AWSKeyValueStore.setPersistenceEnabled(AWSKeyValueStore.java:131)
       at com.amazonaws.internal.keyvaluestore.AWSKeyValueStore.(AWSKeyValueStore.java:12)
       at com.amazonaws.auth.CognitoCachingCredentialsProvider.initialize(CognitoCachingCredentialsProvider.java:425)
       at com.amazonaws.auth.CognitoCachingCredentialsProvider.(CognitoCachingCredentialsProvider.java:5)
       ... 
       <redacted dagger2 dependency module code>

This crash is less frequent than the one posted in this issue, and appears to be affecting all android versions, unlike KeyProvider18 which only affects Android 5 and lower.

In the meantime, we will be rolling back our AWS SDK versions to 2.12.5 until these issues are resolved.

Please let me know if you'd like me to open a separate issue for this crash, and apologies if these messages are spamming your inbox. Thank you!

mutablealligator commented 5 years ago

@iam1492 For the issue where key == null:

KeyProvider18 encrypts the key that encrypts the data and stores the encrypted key in SharedPreferences. From the stack trace, I could see that the encrypted key is found in SharedPreferences. However we are not able to decrypt the encrypted key that is read from SharedPreferences.

Do you see the exception being logged from https://github.com/aws-amplify/aws-sdk-android/blob/87416097c2b9f8e374c64c69c21775f8f00108ec/aws-android-sdk-core/src/main/java/com/amazonaws/internal/keyvaluestore/KeyProvider18.java#L136 line in your Logcat? This log message could help us diagnose why the decryption of the encrypted key could have failed.

@ygnessin I see your issue as a separate issue. From the research I could see that this error could happen if the device's protection status could have changed (when user tries to UNLOCK from LOCK/UNINITIALIZED). Is this issue reproducible on a device you have? If so, can you shed some light on the device protection settings configured and if there are any changes made?

rodrigoarias commented 5 years ago

I'm having lots of crashes because of this. Mainly:

Fatal Exception: java.lang.NoSuchMethodError: android.security.KeyPairGeneratorSpec$Builder.setKeySize
       at com.amazonaws.internal.keyvaluestore.KeyProvider18.initializeRSAKeyFromKeyStore(KeyProvider18.java:154)
Fatal Exception: java.lang.RuntimeException: Unable to create application ar.com.bancar.uala.application.UalaApplication: java.lang.IllegalStateException: Error in initializing the CognitoCachingCredentialsProvider. 
       at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4750)
Caused by java.lang.IllegalStateException: Error in initializing the CognitoCachingCredentialsProvider. 
       at com.amazonaws.auth.CognitoCachingCredentialsProvider.initialize(CognitoCachingCredentialsProvider.java:434)

This is really critical.

ygnessin commented 5 years ago

@kvasukib thanks for looking into this. It makes since that the KeyProvider23 trace I shared is a separate issue, but in addition to that we are also seeing the KeyProvider18 posted in the original issue message. So our app is being affected by both issues.

Unfortunately, I haven't been able to reproduce either of the issues locally, but we are seeing these traces come from production. I still believe that this is happening on app startup, because we are using Dagger2 to initialize cognito and inject it.

Sorry that I can't be of more help right now, and thank you for looking into this critical issue!

Fando commented 5 years ago

We're suffering from this error as well.

AWS Libraries com.amazonaws:aws-android-sdk-kinesis:2.13.2 and com.amazonaws:aws-android-sdk-mobile-client:2.13.2@aar

Device Nexus 7, Android 5.0

When this is called,

new CognitoCachingCredentialsProvider(context, poolId, REGION)

The following error is received.

The error is in KeyProvider18.initializeRSAKeyFromKeyStore(...), in particular the line, if (!keyStore.containsAlias(keyAlias)) ... hangs the device. No stack trace is available beyond this line.

Stack trace leading up to the freeze

 at com.amazonaws.internal.keyvaluestore.KeyProvider18.initializeRSAKeyFromKeyStore(KeyProvider18.java:141)
      at com.amazonaws.internal.keyvaluestore.KeyProvider18.getKey(KeyProvider18.java:72)
      - locked <0x17c1> (a java.lang.Object)
      at com.amazonaws.internal.keyvaluestore.AWSKeyValueStore.setPersistenceEnabled(AWSKeyValueStore.java:138)
      - locked <0x17c2> (a java.lang.Object)
      at com.amazonaws.internal.keyvaluestore.AWSKeyValueStore.<init>(AWSKeyValueStore.java:108)
      - locked <0x17c2> (a java.lang.Object)
      at com.amazonaws.auth.CognitoCachingCredentialsProvider.initialize(CognitoCachingCredentialsProvider.java:425)
      at com.amazonaws.auth.CognitoCachingCredentialsProvider.<init>(CognitoCachingCredentialsProvider.java:190)
mutablealligator commented 5 years ago

Thank you the details and the stack-trace. There are multiple issues here with KeyProvider18.

  1. Call to setKeySize needs to be removed.
  2. Debug key == null. So far I can see that the RSA decrypt of the key fails with an exception. If I could get a stacktrace of the decrypt failure which should be part of the exception key == null I can debug this issue further.
  3. Hang while calling containsAlias. Are there any details around the issue being able to be reproduced locally or consistently? Does it recover from the hang or is it infinite?

Thank you for the patience. I am working on the root-cause.

hvar90 commented 5 years ago

this is a big problem i am having many diferents errors on different devices java.lang.illegalstateexception error in initializing the cognitoCachingCredentialsProvider com.amazonaws.AmazonClientException: Unable to execute HTTP request: Read timed out com.amazonaws.AmazonClientException: Unable to execute HTTP request: Unable to resolve host "sts.amazonaws.com": No address associated with hostname com.amazonaws.AmazonClientException: Unable to execute HTTP request: failed to connect to sts.amazonaws.com/52.94.241.129 (port 443) after 15000ms com.amazonaws.AmazonClientException: Unable to execute HTTP request: SSL handshake timed out com.amazonaws.AmazonClientException: Unable to execute HTTP request: Unable to resolve host "cognito-identity.us-east-1.amazonaws.com": No address associated with hostname

mutablealligator commented 5 years ago

@hvar90 The problem you reported is different from this GitHub issue. The exception you are facing is due to the network being offline in the device that is making a network call.

ygnessin commented 5 years ago

@kvasukib have there been any updates on this? It is preventing us from keeping our SDKs up to date.

Thanks for all your hard work!

alphamu commented 5 years ago

I suspect this issue is related to: https://github.com/aws-amplify/aws-sdk-android/issues/940 My issue when away when I manually delete all of AWS sdk's sharepreferences. The issue seems to come up for accounts that have been delete from Cognito any recreated with the exact same details a few times.

jamesatfish commented 5 years ago

Further to the notes I left against https://github.com/awslabs/aws-mobile-appsync-sdk-android/issues/137, a number of the users who experience this issue with our apps have had their accounts deleted and recreated in Cognito with the same email address (username) on several occasions.

The only way we can restore access for these users is to ask them to clear the application data storage, which obviously clears whichever broken parts of the keystore are preventing Cognito from correctly authenticating.

rodrigoarias commented 5 years ago

Is there any approximate date of when there will be a fix? More than 75% of my app crashes are due to this.

mutablealligator commented 5 years ago

@rodrigoarias Sorry for the delayed response. We are still working on the issue. Currently we have the following two issues:

Crash in API 23-28: UnrecoverableKeyException that occurs intermittently. Crash in API 18-22: Failure during decryption.

Do you have any successful attempts in reproducing the issue locally?

rodrigoarias commented 5 years ago

@kvasukib No, I wasn't able in any of my devices

lwld commented 5 years ago

We are also getting reports of this crash on some users' devices, after updating SNS SDK to 2.13.5 (com.amazonaws:aws-android-sdk-sns:2.13.5)

Devices reported (KeyProvider18.getKey):

Devices reported (KeyProvider23.getKey):

Also not able to reproduce on local devices. If stack traces could be of help, let me know.

SolisNestor commented 5 years ago

Hello, I think I have the same problem and I reproduce it with the following steps:

I think the problem is the cache saved by the application when have enabled the AllowBackup parameter. My problem was solved when setting the parameter AllowBackup to FALSE (Android: allowBackup = “false”)

ygnessin commented 5 years ago

@SolisNestor nice find!

I can confirm that in our app we also have the following in our manifest:

android:allowBackup="true"
android:fullBackupContent="@xml/backup_scheme"

In our backup_scheme.xml there are certain domains that we exclude, for example:

<exclude domain="file" path="instant-run"/>

Perhaps there is a solution for this issue that can be implemented by excluding a certain domain/path from backup?

Thanks!

ekkelenkamp commented 5 years ago

I see the same issues on the example provided on github: https://github.com/awslabs/aws-sdk-android-samples/tree/master/AmazonCognitoAuthDemo

Running the app the first time seems to work fine. Running it a second time, results in the following errors using different Android versions (I'm using th emulators).

I/AWSKeyValueStore: Detected Android API Level = 27 I/AWSKeyValueStore: Using keyAlias = CognitoIdentityProviderCache.aesKeyStoreAlias E/KeyProvider23: Error in accessing the Android KeyStore. java.security.UnrecoverableKeyException: Failed to obtain information about key at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreSecretKeyFromKeystore(AndroidKeyStoreProvider.java:282) at android.security.keystore.AndroidKeyStoreSpi.engineGetKey(AndroidKeyStoreSpi.java:98) at java.security.KeyStore.getKey(KeyStore.java:1062) at com.amazonaws.internal.keyvaluestore.KeyProvider23.getKey(KeyProvider23.java:80) at com.amazonaws.internal.keyvaluestore.AWSKeyValueStore.setPersistenceEnabled(AWSKeyValueStore.java:131) at com.amazonaws.internal.keyvaluestore.AWSKeyValueStore.(AWSKeyValueStore.java:108) at com.amazonaws.mobileconnectors.cognitoauth.Auth.(Auth.java:192) at com.amazonaws.mobileconnectors.cognitoauth.Auth.(Auth.java:44) at com.amazonaws.mobileconnectors.cognitoauth.Auth$Builder.build(Auth.java:473) at com.amazonaws.cognito.android.samples.authdemo.MainActivity.initCognito(MainActivity.java:128) at com.amazonaws.cognito.android.samples.authdemo.MainActivity.onCreate(MainActivity.java:51) at android.app.Activity.performCreate(Activity.java:7009) at android.app.Activity.performCreate(Activity.java:7000) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6494) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) Caused by: android.security.KeyStoreException: Invalid key blob at android.security.KeyStore.getKeyStoreException(KeyStore.java:697) at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreSecretKeyFromKeystore(AndroidKeyStoreProvider.java:283)

lwld commented 5 years ago

We downgraded the SNS SDK from 2.13.5 to 2.12.5 (based on some reports here, it seemed that this might solve the issue for the moment), but still get this error reported from some user devices.

ArthurSav commented 5 years ago

Getting quite a few crashes, using 2.13.4

Caused by java.lang.IllegalStateException
java.lang.IllegalArgumentException: key == null
com.amazonaws.internal.keyvaluestore.KeyProvider18.getKey + 98 (KeyProvider18.java:98)

Is the issue being worked on?

marcaoortega commented 5 years ago

We Downgraded to 2.12.5 now;

Subcribed here, for news , about this issue !

Thanks !

rodrigoarias commented 5 years ago

Any news? Is this getting fixed soon?

shawn-lin-013 commented 5 years ago

Any news? Is this getting fixed soon?

We found some workarounds, but unfortunately this issue has NOT been solved yet. Still getting crashes from user devices.

Caused by java.lang.IllegalStateException
java.lang.IllegalArgumentException: key == null

AWS SDK: 2.13.7

Android OS: Android 4.3 to 5.1

mutablealligator commented 5 years ago

I am actively working on a fix for this problem and will update here when we roll out a fix.

palpatim commented 5 years ago

Also related to:

palpatim commented 5 years ago

We released a fix for this on 2.15.1. Please let us know if you have any questions or continue to see crashes related to retrieving encrypted data.

ekkelenkamp commented 5 years ago

I've been testing with the 2.15.1 release for a week now and haven't seen the issue anymore. Looks like the issue has been fixed. Thanks for the update!

ArthurSav commented 5 years ago

Released 2.15.1 this week and no crashes so far.

rodrigoarias commented 5 years ago

So far so good, thanks for the fix.

desokroshan commented 5 years ago

Thanks for the feedback!

eduprat-chwy commented 4 years ago

Hello, I think I have the same problem and I reproduce it with the following steps:

  • In the manifest file set the parameter allowBackup to True (android: allowBackup = “true”)
  • Install and run the application, get a token with Cognito (At this time everything works fine)
  • Uninstall the app
  • Reinstall and open the application. When trying to get the token the problem is generated

I think the problem is the cache saved by the application when have enabled the AllowBackup parameter. My problem was solved when setting the parameter AllowBackup to FALSE (Android: allowBackup = “false”)

Oh yes! I spent two days in this, can I name you god?