Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encryption / KeyStore Failure Fallbacks [Community Feedback Requested] #2971

Open
tylerjroach opened this issue Jan 13, 2025 · 8 comments
Open
Labels
feature-request Request a new feature

Comments

@tylerjroach
Copy link
Member

tylerjroach commented Jan 13, 2025

Describe the feature request

Amplify Android has received reports of crashes during EncryptedSharedPreferences initialization.

Recently, we attempted a fix:

As shown in some of these crash reports, the default Android master key was reported as unusable. When we detect this, we now attempt to create a new master key for Amplify. While this fix may work in some scenarios, it has not resolved all of the issues.

Unfortunately many of these crashes appear to be due to bugs within the Android KeyStore implementation. Some of these appear to be manufacturer specific bugs.

For these devices, it does not appear possible to use KeyStore based encryption. In order to prevent such crashes, we will now fallback to an In-Memory Key/Value repository.

This behavior is consistent with Amplify v1 and the AWS Android SDK. This approach will allow Amplify to function normally within an app session, however, data will not persist across device restarts (ex: Auth will need to sign in each time a new app instance is opened). This may be sufficient for this small edge case of devices that does not seem to have functioning KeyStore based encryption.

Ultimately, in order for these limited number of devices to operate normally, we would need to soften our encryption stance and allow these devices to store data (ex: Cognito auth tokens and refresh token) in plain text. This may be acceptable to some develpers, as Android's application sandbox already provides its own security mechanisms: https://source.android.com/docs/security/app-sandbox.

This ticket is to request community feedback for an option to fallback to plain text key/value storage in the event that the KeyStore is unusable. This could look something like Amplify.configure(context, allowInsecureDeviceCaching = true) and the value would be false by default.

Copy link
Contributor

This issue was opened by a maintainer of this repository; updates will be posted here. If you are also experiencing this issue, please comment here with any relevant information so that we're aware and can prioritize accordingly.

@4brunu
Copy link

4brunu commented Mar 5, 2025

Hi @tylerjroach, this is an issue we are facing as well.
Unfortunately this seems to be a problem that will not be fixed.
May I suggest that instead of having the EncryptedSharedPreferences or Plain Text options, that you consider a third option by using a plain SharedPreferences where you would store the keys in plain text, but you would store the values encrypted?
By doing this, you would encrypt the values each time you want to write then to the SharedPreferences, and unencrypt them each time you want to read them.
This should be a middle term that offer more security than the plain text option can offer, for those who need it.
Thanks

@github-actions github-actions bot added the pending-maintainer-response Issue is pending response from an Amplify team member label Mar 5, 2025
@tylerjroach
Copy link
Member Author

May I suggest that instead of having the EncryptedSharedPreferences or Plain Text options, that you consider a third option by using a plain SharedPreferences where you would store the keys in plain text, but you would store the values encrypted?

@4brunu I don't believe what you are suggesting would work in these cases. While the stacktrace is within EncryptedSharedPreferences, the actual crash seems to be a complete failure to access the Android KeyStore (with or without EncryptedSharedPreferences). If we can't access they Android KeyStore, we can't properly encrypt values on these devices.

This is how Amplify v1 worked. It did not use EncryptedSharedPreferences, but it did use the Android KeyStore to encrypt the values. I believe that Amplify v1 was still problematic on these devices, and it was quietly falling back to its in memory preferences.

If you have any evidence to the contrary, please let us know and we can investigate further.

@github-actions github-actions bot removed the pending-maintainer-response Issue is pending response from an Amplify team member label Mar 5, 2025
@4brunu
Copy link

4brunu commented Mar 5, 2025

@tylerjroach You are right, the issue is in the Android KeyStore.
What I'm suggesting is using a plain SharedPreferences with encrypted values, but the encrypt/decrypt process would be done without using the Android KeyStore.

@github-actions github-actions bot added the pending-maintainer-response Issue is pending response from an Amplify team member label Mar 5, 2025
@tylerjroach
Copy link
Member Author

Without the Android KeyStore, there is no way to secure the encryption/decryption key, especially as an open source library. The Android KeyStore is a vault (most of the time, hardware backed) that is able to act as a secure storage location to hold encryption keys. Without it, the key would have to be stored within the application sandbox, defeating the purpose of encryption as anyone could decrypt.

@github-actions github-actions bot removed the pending-maintainer-response Issue is pending response from an Amplify team member label Mar 5, 2025
@4brunu
Copy link

4brunu commented Mar 5, 2025

Thanks for the explanation, I thought that maybe there would be some alternative 👍

@github-actions github-actions bot added the pending-maintainer-response Issue is pending response from an Amplify team member label Mar 5, 2025
@4brunu
Copy link

4brunu commented Mar 6, 2025

@tylerjroach one last question, since you mention that this is especially dificult as an open source library, what if we pass to the app the responsibility of storing the encryption keys?
There are multiple possibilities to the app to do this, the app could crypt and decrypt the encryption keys to save them on this, or store them server side.

@tylerjroach
Copy link
Member Author

the app could crypt and decrypt the encryption keys to save them on this, or store them server side.

Without a device KeyStore, any attempts to secure the encryption key would be obfuscation at best. Ex: in the server-side case, you would need to authenticate with the server (which would involve storing some other sort of key which can't be secured in the KeyStore).

We do not expect you to see a large number of devices with failing KeyStore's. In the limited set of problematic devices, it's up to the hardware manufacturer to fix (It's possible some of these issues are already fixed if the end user was updated to the latest OS version the hardware manufacturer provided. Can you please share the # or percentage of devices you are seeing on your application with this issue?

The option to allowInsecureDeviceCaching option would allow these faulty devices to continue working in a less secure mode.

I had also explored another option, which was to let the developer inject their own Key/Value Repository, leaving the implementation up to the developer (#2939 (comment)). After exploring this implementation, it would have resulted in a number of confusion points for the customer.

@github-actions github-actions bot removed the pending-maintainer-response Issue is pending response from an Amplify team member label Mar 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request Request a new feature
Projects
None yet
Development

No branches or pull requests

2 participants