Status Update
Comments
ey...@gmail.com <ey...@gmail.com> #2
I had to rollback to an older version. I've had hundreds of crashes reported because of this.
jm...@google.com <jm...@google.com> #3
Sorry about this, can you provide some additional context:
What percentage of your app installs are crashing? Is it isolated on any small number of OEMs or android versions?
ey...@gmail.com <ey...@gmail.com> #4
1% of our active users.
According to Crashlytics it looks like it's mostly Motorola (Moto Z), followed by LG (G7 ThinQ and V20, and then Pixel 2 and Pixel 2 XL, then Blu Pure View. Equally spread across Android 8-10.
It looks like the majority (85%) of the crashes are happening when the app is in the background, i.e. a notification wakes it up.
th...@google.com <th...@google.com> #5
Have you observed anything log containing the AndroidKeysetManager tag?
ey...@gmail.com <ey...@gmail.com> #6
I haven't been able to repro this locally, and I don't have access to logs on the users' devices. I've tried to get it to happen on my device, and I monitored the logs and didn't see AndroidKeysetManager anywhere.
ey...@gmail.com <ey...@gmail.com> #7
Does 1.1.0-alpha01 address this?
ey...@gmail.com <ey...@gmail.com> #8
I haven't been able to repro this locally, however the count of users and crashes that this is happening for is steadily rising (I released an update that rolled the library version back, but it doesn't have wide adoption yet).
I sampled a bunch of them, and it looks like this predominantly happens when an FCM wakes up the device while in the background.
as...@tradingview.com <as...@tradingview.com> #9
jm...@google.com <jm...@google.com> #10
Alpha 1.1.0 adds support for Lollipop devices, it may not help in this case.
We're working on adding better exception handling in these cases. There is a small percentage of devices that will not be able to use the AndroidKeyStore.
ey...@gmail.com <ey...@gmail.com> #11
Got a report of this happening on a co-worker's device (unfortunately can't get device physically because of COVID, but I will be sending them builds to try and diagnose more). They confirmed:
- The issue occurred after opening the app from a notification (posted locally, not through FCM)
- After the crash, they can not recover
ey...@gmail.com <ey...@gmail.com> #12
#10 when you say "small percentage of devices" does that mean models, or physical devices? Because the current predominant device this is happening on is Pixel 2, but there are many more Pixel 2s that don't have the issue.
And if they aren't able to use the AndroidKeyStore will they still be able to use this library?
jm...@google.com <jm...@google.com> #13
I mean physical devices, some work and some don't - even the same phone model. I don't have any concrete numbers to share.
Yes, the library still works, we do a self test to check the keystore in the newer versions RC2+ to see if the Keystore is operating properly. In these cases where the Keystore is broken, the Keystore is not used to wrap the key. You do still get the protection of Android's full disk encryption/file based encryption depending on Android version.
For more info, bullet 3 describes what I'm talking about.
ey...@gmail.com <ey...@gmail.com> #14
OK that shouldn't be related to what I'm seeing. My minSdk is 24.
jm...@google.com <jm...@google.com> #15
Yeah, we handle devices as if they are running Lollipop in broken Keystore scenario.
This was hard for to test and reproduce. We're working on refining this to nail down all the different versions of phones with issues so that you don't need to worry about it.
Thanks for the info and patience.
st...@salesforce.com <st...@salesforce.com> #16
I've been having this kind of issue with decryption with Tink separately and AndroidX EncryptedSharedPreferences. This doesn't seem to be because of EncryptedSharedPreferencs, but more that something is up with Tink or how Tink is working with Android.
I'm also seeing a large uptick of failures per day. well over 10,000 users run into decryption failures from EncryptedSharedPreferences.
st...@salesforce.com <st...@salesforce.com> #17
To add on, there is a similar GeneralSecurityException happening on the Tink issues.
I don't have anything conclusive, but I'm testing out a theory that is related to
we do a self test to check the keystore in the newer versions RC2+ to see if the Keystore is operating properly
I'm trying to isolate if the Android keystore is broken and so Tink is haven't a problem trying to create a consistent keyset that it can use between sessions/instances of Aead
.
ey...@gmail.com <ey...@gmail.com> #18
They suggest not using an AndroidKeystore backed MasterKey. Not sure what the migration story would look like there, and I'm trying not to think about it, because I'm currently trying to figure out how to wipe affected users data so they can at least open the app and start over.
jm...@google.com <jm...@google.com> #19
Hey guys, yeah we are working on it. Thai is also CC'ed on this bug. We hope to have this resolved such that you won't need to worry about which devices have a bad keystore. This is still a small percentage of devices though, so it doesn't make sense to not use it for encrypting data.
jw...@akamai.com <jw...@akamai.com> #20
I assume the app will work again after clearing data but I'll leave it in this state for now in case there are any debugging steps to try. No mention of AndroidKeysetManager in logs.
tink 1.4.0-rc2
androidx.security:security-crypto 1.1.0-alpha01
st...@salesforce.com <st...@salesforce.com> #21
I've noticed the same thing with Pixel3 and Pixel 2 devices as well. I am awfully puzzled because the AndroidKeyStore I would have to assume is more reliable as it has been in Android for so many versions and with Symmetric keys since Marshmallow, one would expect to have it run stable.
Jon, as for the small percentage, yes, I see this fail for a small percentage of 0.1% right now, but for lets say 1 million users, that is 1000 users that are affected. Still seems like a lot of affected users.
ey...@gmail.com <ey...@gmail.com> #22
I've seen this happen 2 different ways:
-
We have a BroadcastReceiver that gets called when the app is updated in the Play Store (
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
). Sometimes when that happens, we get aCould not decrypt value. decryption failed
error, but it doesn't appear to be permanent, because the app continues to work after that. -
We get a
Could not decrypt value. decryption failed
(usually in the background when the app is woken up by FCM), and in that case it doesn't recover. I test for that by putting a sanity check key-value into the shared prefs. If I can't read that when the app starts (or the value comes back incorrect - which has happened) I delete the shared prefs files, and restart the process (which sucks because it means that the user loses their session, and any queued data that hadn't been synced to our backend yet).
jm...@google.com <jm...@google.com> #23
Hey all, we have an update coming with the next Jetpack Security release which includes Tink 1.4.0. This will fix R8/Proguard issues as well as more gracefully handle decryption issues. For more info, please see:
We did some more research on our side and we are certain that most of these errors are caused by the keystore being busy, which will give an occasional error. This happens more often in the background because services that all wake up at the same time might be trying for keystore access. I will update this bug when it goes live. Appreciate the patience all.
st...@salesforce.com <st...@salesforce.com> #24
We did some more research on our side and we are certain that most of these errors are caused by the keystore being busy, which will give an occasional error. This happens more often in the background because services that all wake up at the same time might be trying for keystore access
Thanks for this research into the Android keystore. What are the recommendations to avoid or detect this problem with keystore being busy? What is the exact error that you receive from the Android keystore for this? I've seen the same users fail over and over again on different sessions and different days.
jd...@google.com <jd...@google.com> #25
Jon asked me to write about the situation where Keystore is busy.
We have the unfortunate situation that Keystore will only support 15 operations at the same time (4 in the case of Strongbox). When you create a crypto object you allocate one of these slots and the allocation will always succeed even if all slots are taken. Currently, the least recently used operation will simply get evicted, and that operation will fail with error code -28.
Now, it is unclear if this is actually what you are running into here, because the root cause of the exceptions reported above seems to be truncated. But in the scenario where many apps wake up at the same time trying to perform crypto operations it may be that on some devices more than 15 apps are competing for operations slots and eventually some might get evicted before they can complete their operation.
In this case you could retry, but careful! If 15+ apps are retrying in a tight loop you could end up in a situation where no app is able to complete their operations. You end up in a life lock of 15+ apps draining the battery without making progress. So a back off with a randomized delay would help.
I know that this Situation is unfortunate and our hands are tied between hardware dependencies and API conformity to fix this issue. But our plan is to mitigate this issue in Android S.
ey...@gmail.com <ey...@gmail.com> #26
So if this issue occurs do we need to retry with a new instance of EncryptedSharedPreferences
, or retry the operation using the same instance of EncryptedSharedPreferences
?
st...@salesforce.com <st...@salesforce.com> #27
Looking at How Tink uses the AndroidKeystore, I think we'd need a new instance of EncryptedSharedPreferences
because Tink will use the Android Key store only for decrypting the tink keyset, and after that, Tink has no need for the Android Keystore. I'll have to look at my logs to see how often I see this -28
error code though. I don't recall seeing it at the same frequency of the failures I see in production.
pe...@gmail.com <pe...@gmail.com> #28
jm...@google.com <jm...@google.com> #29
This should be resolved as 1.0.0-RC3, and if you're using the alpha library 1.1.0-alpha02.
Could you please check and verify? Will leave this bug open.
ey...@gmail.com <ey...@gmail.com> #30
I updated to 1.1.0-alpha02 and I'm still seeing the same issue with the same Exception and message.
I added a retry for each crypto op 5 times with backoff.
st...@salesforce.com <st...@salesforce.com> #31
I put 1.0.0-RC3 in our next build. But worried since 1.1.0-alpha02 sounds like it still has the same problem :(
But retrying the op to get 5 times won't fix the problem probably because the Android keystore isn't used in those retries. Tink is using the Android Keystore when you created the instance of EncryptedSharedPreference. Inside the EncryptedSharedPreference asks Tink to create instances of Aead that is supported by Tink keysets. The Tink keysets are encrypted/decrypted by the Android Keystore, and used only when creating the Aead instance. So retrying should mean recreating the EncryptedSharedPreference to trigger Tink to attempt to decrypt the keyset.
Btw, are you reinstalling your app every time when you see this problem? I'm wondering what your experience might have been with
- Clearing app data
- Reinstalling the app
- Removing the master key that Tink uses to encrypt/decrypt the keyset
We had one user come out of this decryption problem by restarting their phone. I don't like that approach at all.
ey...@gmail.com <ey...@gmail.com> #32
I only had access to one device that this was happening on (a co-workers wife's device), and I didn't want to clear the app data so that we could build out a way to detect the issue.
She had tried restarting the device, and that didn't solve it. Our solution is to detect the issue, clear the EncryptedSharedPreferences (and anything that relies on it), and then use ProcessPhoenix to restart the app. That was the only thing we had tried at the time that worked.
I actually forgot to update my fix to retry creating the EncryptedSharedPreferences instance, so I'll have to try again with that.
th...@google.com <th...@google.com> #33
that was already overwritten. In earlier versions of Tink and Jetpack
Security, whenever a key can't decrypt correctly Tink would overwrite it
with a new one. This is a stupid design mistake that I made because I
thought the key is usuable anyway. It didn't come to me that the failure
might be transient, and a simple retry would be sufficient.
In 1.4.0, Tink wouldn't erase existing keys, but it'd throw a
KeyStoreException.
Again, I'm deeply sorry for any inconvenience caused.
> I actually forgot to update my fix to retry creating the
> EncryptedSharedPreferences instance, so I'll have to try again with that.
>
I plan to add a simple retry mechanism to Tink itself. It should be
available in 1.5.0 released in two weeks, which should make its way to
Jetpack Security shortly after.
ey...@gmail.com <ey...@gmail.com> #34
So for the short term if we detect a KeystoreException we should try creating a new instance of EncryptedSharedPreferences?
th...@google.com <th...@google.com> #35
st...@salesforce.com <st...@salesforce.com> #36
Thai and Jon, what is our recommended retry backoff? I'm worried that if we receive a KeyStoreException and immediately request again, we'd get the same Keystore Exception
ne...@gmail.com <ne...@gmail.com> #37
"I plan to add a simple retry mechanism to Tink itself. It should be
available in 1.5.0 released in two weeks, which should make its way to
Jetpack Security shortly after."
Two weeks was gone. When tink 1.5.0 will be released? And when new version of androidx.security:security-crypto with new Tink will be relrased?
ne...@gmail.com <ne...@gmail.com> #38
th...@google.com <th...@google.com> #39
I'm sorry for the slow response. I was optimistic when I said 2 weeks.
We're wrapping up 1.5.0 feature sets and I'll add this retry mechanism this
week. If there's no last minute surprise I think we'll be able to release
something early the week after.
On Sat, Aug 22, 2020 at 11:11 PM <buganizer-system@google.com> wrote:
st...@salesforce.com <st...@salesforce.com> #40
This is kind of what I did but still waiting for data to trickle back
private fun createKeysetManager(): AndroidKeysetManager? {
val keysetManagerResult = attemptCreateKeysetManager()
when (keysetManagerResult) {
is CreateKeysetManagerResult.RecoverableFailure -> attemptCreateKeysetManager(storage).keysetManager
else -> keysetManagerResult.keysetManager
}
}
private fun attemptCreateKeysetManager(): CreateResult {
return try {
// create AndroidKeysetManager with keystore
} catch (e: KeyStoreException) {
RecoverableFailure
} catch (e: GeneralSecurityException) {
UnrecoverableFailure
} catch (e: IOException) {
UnrecoverableFailure
}
}
private sealed class CreateResult(val keysetManager: AndroidKeysetManager?)
object UnrecoverableFailure : CreateResult(null)
object RecoverableFailure : CreateResult(null)
class CreateSuccess(keysetManager: AndroidKeysetManager) : CreateResult(keysetManager)
I don't know if it is going to work, I just hope it does :(
rb...@unwire.com <rb...@unwire.com> #41
Is the issue unrecoverable? And if it is, how can retrying help?
pe...@gmail.com <pe...@gmail.com> #42
I'm also feeling a little unsure of what a robust implementation of Jetsec should look like now.
I'm working on an app that uses EncryptedSharedPreferences to store both preferences and encryption keys (stored as preferences) to Room backed by SQLCipher. We use this for encrypted caching on-device. The whole app is dependent on EncryptedSharedPreferences/SQLCipher, so getting edge cases correct is really important for us.
We're currently seeing ~1.5% of app installs crash after a recent release that updated from alpha02 to rc02, possibly due to the overwriting of keys mentioned
I think as of rc03 the correct action for #33 is to catch KeyStoreException and build a new instance of EncryptedSharedPreferences? This is somewhat problematic for us since we use Dagger to @Inject SharedPreferences with a single instance (app-wide) of EncryptedSharedPreferences. I'm not sure if we can dynamically ask Dagger to build a new instance once we see KeyStoreException. Maybe I can scope it such that a new instance is created for each @Inject (many instances using the same filename and same key)? Would that increase the pressure on the Keystore, potentially increasing the need for retries (coming in Tink 1.5 / Jetsec rc04?)? I'm currently thinking I might be able to wrap SharedPreferences and instead @Inject something like SharedPreferencesProvider. This would have methods for rebuilding a new instance of EncryptedSharedPreferences when KeyStoreException is encountered. I think this would work, but would be less than ideal for clients of the API to have to do this. It would be more ideal if we could re-use the same instance, but being able to clear()/create new keys.
Apart from that I'm not sure what other cases I'd need to handle; specifically I'm not sure in which cases GeneralSecurityException can be thrown.
Any tips for what a robust implementation should look like in rc03? And how it might change in rc04 (i.e keystore retries via Tink 1.5)? Thank you!
pe...@gmail.com <pe...@gmail.com> #43
Oh, since SharedPreferences is an interface, it would probably be possible for me to create WrappedEncryptedSharedPreferences and leave client code unchanged. Internally, that might wrap each call, catch KeystoreException, replace the wrapped instance of EncryptedSharedPreferences, and clear SQLCipher/re-key. Until rc04, it could additionally catch GeneralSecurityException and do retry with backoff (maybe it'd be valuable to add something like KeyStoreThrottledException to decipher this from other GeneralSecurityExceptions?).
I'm not sure any of the above is helpful, but at the least it might show what clients of the 1.0 API might be considering.
Thank you all for your hard work on Jetsec- it's an incredibly useful library for us, and light years better than we could do on our own!!
as...@tradingview.com <as...@tradingview.com> #44
ne...@gmail.com <ne...@gmail.com> #45
"I plan to add a simple retry mechanism to Tink itself. It should be
available in 1.5.0 released in two weeks, which should make its way to
Jetpack Security shortly after."
2 months have passed
When tink 1.5.0 will be released?
And when new version of androidx.security:security-crypto with new Tink will be relrased?
We have a ton of crashes
th...@google.com <th...@google.com> #46
th...@google.com <th...@google.com> #47
The good news is we've resolved all the other blockers for 1.5.0.
th...@google.com <th...@google.com> #48
>Is the issue unrecoverable? And if it is, how can retrying help?
Here's a summary of the situation so far.
1/ Background
Jetpack depends on Tink which depends on Android Keystore.
When you encrypt something with Jetpack, it calls Tink which generates a keyset and wraps it with a main key in Android Keystore. The wrapped keyset is stored in shared preferences, but the main key resides within Android Keystore. When you decrypt something, Jetpack calls Tink, which calls Android Keystore to unwrap its keyset and then use the unwrapped keyset to decrypt data.
2/ The problems
2.1/ Not fixed: On many phones, Android Keystore is implemented by a third-party OEM, and some implementations are buggy.
2.2/ Not fixed: Android Keystore itself also has an unfortunate limitation that it will only support 15 operations at the same time (4 in the case of Strongbox). When you create a crypto object you allocate one of these slots and the allocation will always succeed even if all slots are taken. Currently, the least recently used operation will simply get evicted, and that operation will fail with error code -28.
2.3/ Fixed: in earlier versions, when Tink couldn't unwrap an existing keyset, it'd assume that either the main key or the wrapped keyset is corrupted, and it'd automatically attempt to generate new key material. Because Android Keystore could have failed with a transient code -28 error, we've changed Tink to not always generate new key material. At the moment when Tink can't unwrap an existing keyset, it'd throw
* InvalidKeyException, if the wrapped keyset is corrupted; or
* KeyStoreException, if Android Keystore threw an error.
In other words, instead of silently attempting to fix Keystore failures, Tink now just reports them. This is a better approach because it allows you to decide what you want to do.
2.4/ Fixed: Tink runs a self-test to decide whether it wants to use Android Keystore or not. In earlier versions, the test performed a bunch of consecutive Keystore operations, which, unfortunately, could have made error code -28 more likely to happen. We've changed the test to perform a single Keystore operation.
4/ When retry might help
If Keystore failed with error code -28, a simple retry might work. This is what I planned to add to Tink, but as reported in #47, I've encountered some issues.
5/ Your options
If you encounter a lot of errors, here are your options:
* Waiting for 1.5.0. But again, it might not include any retry mechanism.
* Implementing a retry mechanism yourself. That if, whenever you encounter a KeyStoreException, wait for a random number of ms and call Tink again.
* Removing existing encrypted data. If a retry doesn't work, it's likely that the encryption key had been lost, probably because of one of the problems list above. Your best course of action is, unfortunately, to clearing existing data.
Once again, I'm deeply sorry for these failures. It's really hard to design a robust solution when you can't have a reliable storage.
ju...@solita.fi <ju...@solita.fi> #49
- Would a retry mechanism possibly also help with GeneralSecurityException as well as KeyStoreException?
- Could EncryptedSharedPreferences thread-safety be an issue here? I understand it's methods are not thread-safe, so if proper synchronization is missing, could that cause issues like this?
jd...@google.com <jd...@google.com> #50
FYI. Keystore, being security critical, is one of the components that we develop in AOSP, which allows me to bring this to your attention. As you can see from the link below, Android Keystore is currently being rewritten in Rust. If you look at keystore2/src/operation.rs
around line 400
, you'll find the new pruning strategy that may make it into the next Android release. TLDR: As a result starting an operation may now, transiently, fail, but well-behaved clients/apps have a better chance of finishing an operation once it was successfully created. Let me know what you think. You can leave comments on the CL as long as is under review.
rb...@unwire.com <rb...@unwire.com> #51
We are facing two different exceptions, one being GeneralSecurityException and the other KeyStoreException.
And based on what I can see in comments:
- GeneralSecurityException is unrecoverable
- KeyStoreException is recoverable (a simple retry might fix this)
Is my understanding correct?
jd...@google.com <jd...@google.com> #52
KeyStoreException can have many causes. You really have to check the nested error code to decide what to do.
A little nitpicking regarding an earlier comment claiming that Keystore is vendor specific. AndroidKeystore comprises the JCA/JCE SPI (service provider interface) which calls into the Keystore daemon. These are part of the Android framework with the SPI being linked into each Keystore client (think app) and the daemon - well - running as a process in its own right. The vendor specific component is called KeyMint (formerly Keymaster) and comprises a HAL service process and an implementation running in a trusted execution environment (TEE) like ARM TrustZone or a secure element (SE), i.e., in the case of Strongbox. The Keystore daemon uses the KeyMint back end to provide its services. Keystore stores the key material and exerts access control (so that apps only get access to their own keys), while the KeyMint back end performs key generation, performs cryptographic operations, enforces key usage restrictions, and cryptographically binds the key material to the device to prevent extraction.
You can find the Keystore response codes
mb...@doximity.com <mb...@doximity.com> #53
I am seeing this same error in our app after adding security-crypto. We are also seeing that the failure generally occurs in the background when a receiver tries to wakeup the app. I have been unable to reproduce this myself but have a hunch is has to do with the direct-boot. It looks like this thread has the idea pinned to KeyStore being busy. I am thinking it is just not available yet because the device is still locked. Has anyone had success with instantiating EncryptedSharedPreferenced using appContext.createDeviceProtectedStorageContext()
?
bo...@gmail.com <bo...@gmail.com> #54
What's the status of both tink 1.5.0 and an updated release for androidx security that helps to mitigate these issues? I find it very hard to reason about how to mitigate from the app itself, especially when actually reproducing the various ways this issue appears is very hard or not possible for us so far.
as...@tradingview.com <as...@tradingview.com> #55
When AndroidX Security with tink 1.5.0 will be released?
ne...@gmail.com <ne...@gmail.com> #56
+
Any info ?
pe...@gmail.com <pe...@gmail.com> #57
Just a follow up to say #42 / #43 did end up working for my app. After a review of every crash from a version that used RC2, we noticed we only had occurrences of SecurityException with the message Could not decrypt value. decryption failed
. Specifically, we did not have any occurrences of Could not decrypt key. decryption failed
.
Based on that, I wrote a wrapper that implements the SharedPreferences interface, wrapped each call, i.e.:
override fun getString(key: String?, defValue: String?): String? = try {
encryptedPreferences.getString(key, defValue)
} catch (e: SecurityException) {
inspect(e)
throw e
}
Then inspect()
just looked for the exception message: Could not decrypt value. decryption failed
and did the recovery.
We have Dagger inject this wrapper any time @Inject SharedPreferences is called.
For us, because we're using Dagger (and also needed to re-initialize SQLCipher), recovery looked like:
-
Set a persistent flag that will be visible on the next reboot (we used a separate, non-encrypted SharedPreferences instance, but a temporary file would work just as well.)
-
Restart the app programmatically (we used Jake Wharton's ProcessPhoenix)
-
While initializing, see that the persistent flag (Shared pref, file, etc) exists, then delete the EncryptedSharedPreferences file (and anything else that may need to be reset; for us, SQLCipher).
-
Delete the flag from #1.
-
Let the normal Dagger setup occur, as if it were a clean install (create an EncryptedSharedPreferences file, init SQLCipher, etc.)
This fixed all occurrences for us (again, we were only seeing Could not decrypt value. decryption failed
. YMMV.)
Hope this is helpful to someone else. :)
ou...@gmail.com <ou...@gmail.com> #59
and this is the release notes for Android : - When a call to Android KeyStore failed, Tink will wait a random number of milliseconds (up to 100) before retrying one more time.
Still waiting for SP to include this in next release.
as...@tradingview.com <as...@tradingview.com> #60
"I plan to add a simple retry mechanism to Tink itself. It should be
available in 1.5.0 released in two weeks, which should make its way to
Jetpack Security shortly after."
Today is November 4 😭😭😭😭😭
3 month
as...@tradingview.com <as...@tradingview.com> #61
jm...@google.com <jm...@google.com> #62
Hey all, we're working on integrating Tink into the next Jetpack release. Will update when we have the date solidified. Thanks!
al...@gmail.com <al...@gmail.com> #63
lu...@remind101.com <lu...@remind101.com> #64
+1 to getting an ETA for this. This will inform us if we should carve out time to build to either: a retry ourselves or to clear out data held in EncryptedSharedPreferences
.
ne...@gmail.com <ne...@gmail.com> #65
pm...@google.com <pm...@google.com> #66
A new jetpack security release that includes Tink v1.5 is now available:
Please, update to this version and let us know if you still see the problem.
mo...@gmail.com <mo...@gmail.com> #67
Good advice is probably not easy to get ATM, but what would you recommend to us? Downgrade to an older version (which?) or use 1.1.0-alpha03?
mo...@gmail.com <mo...@gmail.com> #68
We have deployed a version with 1.1.0-alpha03
to a part of our userbase yesterday. We have now gotten 10 crashes from 2 users. Devices:
- Samsung Galaxy A20e - Android 10 (SDK 29)
- Samsung Galaxy Tab S2 - Android 7.0 (SDK 24)
By now I don't know whether the version upgrade fixed something (thanks to the retrying) or whether we just haven't received enough data to be able to compare before and after.
Logcat:
java.lang.RuntimeException:
at android.app.ActivityThread.handleBindApplication (ActivityThread.java:6998)
at android.app.ActivityThread.access$1300 (ActivityThread.java:270)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2051)
at android.os.Handler.dispatchMessage (Handler.java:107)
at android.os.Looper.loop (Looper.java:237)
at android.app.ActivityThread.main (ActivityThread.java:7948)
at java.lang.reflect.Method.invoke (Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1075)
Caused by: com.google.crypto.tink.shaded.protobuf.InvalidProtocolBufferException:
at com.google.crypto.tink.shaded.protobuf.GeneratedMessageLite.parsePartialFrom (GeneratedMessageLite.java:1566)
at com.google.crypto.tink.shaded.protobuf.GeneratedMessageLite.parseFrom (GeneratedMessageLite.java:1664)
at com.google.crypto.tink.proto.Keyset.parseFrom (Keyset.java:957)
at com.google.crypto.tink.integration.android.SharedPrefKeysetReader.read (SharedPrefKeysetReader.java:84)
at com.google.crypto.tink.CleartextKeysetHandle.read (CleartextKeysetHandle.java:58)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.read (AndroidKeysetManager.java:328)
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)
bo...@google.com <bo...@google.com>
th...@google.com <th...@google.com> #69
If you still encounter a lot of errors, it's likely that the encryption key had been lost, probably due to one of the problems listed in comment 48. Your best course of action is to clear existing data and try again.
th...@google.com <th...@google.com> #70
Re update #57: I believe it works because you deleted the broken EncryptedSharedPreferences file (which was probably encrypted with a key that had been lost). I recommend everybody doing this. Please report back if you still encounter errors after.
mo...@gmail.com <mo...@gmail.com> #71
Thanks bo and th, will likely implement that tomorrow. Can you please tell me how we can simulate a broken Encrypted Sharedpreferences file? I tried some things but it doesn't give me the desired exception.
th...@google.com <th...@google.com> #72
Try something like this
// Test that Tink throws an IOException if can't decode the value in Shared Pref as a hex string.
@Test
public void testBuilder_invalidKeysetString_shouldThrow() throws Exception {
// Generate a corrupt keyset.
String keysetName = randomString();
SharedPreferences.Editor editor =
PreferenceManager.getDefaultSharedPreferences(
ApplicationProvider.getApplicationContext().getApplicationContext())
.edit();
String nonHexValue = randomString().substring(1); // Remove a char, it will be a non-hex value.
boolean success = editor.putString(keysetName, nonHexValue).commit();
assertThat(success).isTrue();
assertThrows(
IOException.class,
() ->
new AndroidKeysetManager.Builder()
.withSharedPref(
ApplicationProvider.getApplicationContext(), keysetName, null /* prefFileName*/)
.withKeyTemplate(EcdsaSignKeyManager.ecdsaP256Template())
.build());
}
pe...@gmail.com <pe...@gmail.com> #73
Will Tink 1.5.0 eventually be included in the 1.0 branch? Alternatively, anything to watch out for when updating from 1.0.0-rc03 to 1.1.0-alpha03?
th...@google.com <th...@google.com> #74
th...@google.com <th...@google.com> #75
Please let us know if deleting old data doesn't work.
ce...@gmail.com <ce...@gmail.com> #76
mo...@gmail.com <mo...@gmail.com> #77
An update to my comments #68 and #71: We decided to stop using EncryptedSharedPreferences for now to avoid crashes :(. Can't tell you whether it got fixed or not now.
th...@google.com <th...@google.com> #78
Can you give us a full stack trace?
sm...@gmail.com <sm...@gmail.com> #79
maybe rc04 is good until now
x....@saltosystems.com <x....@saltosystems.com> #80
The 1.0.0-rc04
shouldn't be the way to go, they just updated Tink to 1.5.0
, and this change was already included in 1.1.0-alpha03
. The proper way would be a fix on the 1.1.0
version since it also supports API level 21+.
[Deleted User] <[Deleted User]> #81
Android 5.1.1 update mi security mi security mi security mi security update 5G network update v7a update miui 10 miui 13 update new update for redmi 2 prime any way
[Deleted User] <[Deleted User]> #82
Android 5.0 update 6.0 update mi security any way
la...@doclerholding.com <la...@doclerholding.com> #83
Could you give me an ETA for 1.1.0 release or RC? I would like to use it in production but the alpha state means it isn't stable. How risky to use it in production? Could you recommend it?
pa...@gmail.com <pa...@gmail.com> #84
I am removing encrypted shared prefs and vowing never to use alpha releases again.
os...@gmail.com <os...@gmail.com> #86
lt...@gmail.com <lt...@gmail.com> #87
xa...@gmail.com <xa...@gmail.com> #88
Since this blocking issue was reported more than a year ago, could we please have an update of its current state?
Thanks a lot!
Re...@remind101.com <Re...@remind101.com> #89
> * Removing existing encrypted data. If a retry doesn't work, it's likely that the encryption key had been lost, probably because of one of the problems list above. Your best course of action is, unfortunately, to clearing existing data.
mean deleting the EncryptedSharedPreferences file or the key material or both? I'm not using 1.1.0 yet. How do I perform this deletion?
Thanks
Re...@remind101.com <Re...@remind101.com> #90
ar...@gmail.com <ar...@gmail.com> #91
Clearing existing data not help. Still getting a lot of crashes
cu...@gmail.com <cu...@gmail.com> #92
se...@gmail.com <se...@gmail.com> #93
ca...@gmail.com <ca...@gmail.com> #94
xa...@gmail.com <xa...@gmail.com> #95
Absolutely agree. A fix, change of priority, or some fallback guidance would be needed for the community who want to use security features on the platform. This seemed to be the purpose of this library.
ce...@gmail.com <ce...@gmail.com> #96
at...@sqli.com <at...@sqli.com> #97
kr...@etrade.com <kr...@etrade.com> #98
ri...@gmail.com <ri...@gmail.com> #99
ve...@gmail.com <ve...@gmail.com> #100
es...@codigodelsur.com <es...@codigodelsur.com> #101
xa...@gmail.com <xa...@gmail.com> #102
Does anybody known if this issue still persist with the
ak...@gmail.com <ak...@gmail.com> #103
It's really a big problem, we are not able to deliver a stable build because of this crash.
dm...@gmail.com <dm...@gmail.com> #104
dm...@gmail.com <dm...@gmail.com> #105
ca...@gmail.com <ca...@gmail.com> #106
As for the 'decryption failed' issue, we have started experiencing it lately too, using the latest stable release version (1.0.0) and updating to the recent alpha version seemingly did not help.
From my observation, we have two occurrences of the issue - one only on a handful of Xiaomi devices in production and the other is easily reproducible on many of our devices in the test farm.
From my observation, the overall issue started occurring after we split some data to a separate preference file and we switched the coroutine context to the IO dispatcher.
It seems that using a Default Dispatcher, that has a limited pool of threads, helps fix the issue. Is it safe though to use a Dispatcher whose pool of threads varies from device to device? Does the Keystore's "business" (reference to the limitation to 15 operations) gets better on processors with more cores?
I'd like someone, ideally from Google, to support or deny this idea. Or could the fact that we now use multiple preference files introduce the issue?
va...@wandera.com <va...@wandera.com> #107
[Deleted User] <[Deleted User]> #108
We are experiencing a similar crash recently. We were storing some data in the EncryptedSharedPref, but we decided to move them to Preference DataStore. It won't be encrypted anymore, but we decided that's acceptable for our use case.
The crash happens during the migration, affecting few devices at the moment (android 9 to 13, OnePlus6, OnePlus8T, Samsung Galaxy A20e)
We're not able to reproduce it.
Version 1.1.0-alpha02
.
Maybe someone here has some suggestion on how to handle this.
Here is the stacktrace:
Exception java.lang.SecurityException: Could not decrypt key. decryption failed
at androidx.security.crypto.EncryptedSharedPreferences.decryptKey (EncryptedSharedPreferences.java:610)
at androidx.security.crypto.EncryptedSharedPreferences.getAll (EncryptedSharedPreferences.java:400)
at androidx.datastore.migrations.SharedPreferencesMigration.shouldMigrate (SharedPreferencesMigration.kt:152)
at androidx.datastore.core.DataMigrationInitializer$Companion$runMigrations$2.invokeSuspend (DataMigrationInitializer.kt:44)
at androidx.datastore.core.DataMigrationInitializer$Companion$runMigrations$2.invoke (DataMigrationInitializer.kt)
at androidx.datastore.core.DataMigrationInitializer$Companion$runMigrations$2.invoke (DataMigrationInitializer.kt)
at androidx.datastore.core.SingleProcessDataStore$readAndInit$api$1.updateData (SingleProcessDataStore.kt:337)
at androidx.datastore.core.DataMigrationInitializer$Companion.runMigrations (DataMigrationInitializer.kt:42)
at androidx.datastore.core.DataMigrationInitializer$Companion.access$runMigrations (DataMigrationInitializer.kt:23)
at androidx.datastore.core.DataMigrationInitializer$Companion$getInitializer$1.invokeSuspend (DataMigrationInitializer.kt:33)
at androidx.datastore.core.DataMigrationInitializer$Companion$getInitializer$1.invoke (DataMigrationInitializer.kt)
at androidx.datastore.core.DataMigrationInitializer$Companion$getInitializer$1.invoke (DataMigrationInitializer.kt)
at androidx.datastore.core.SingleProcessDataStore.readAndInit (SingleProcessDataStore.kt:348)
at androidx.datastore.core.SingleProcessDataStore.readAndInitOrPropagateFailure (SingleProcessDataStore.kt:311)
at androidx.datastore.core.SingleProcessDataStore.handleRead (SingleProcessDataStore.kt:261)
at androidx.datastore.core.SingleProcessDataStore.access$handleRead (SingleProcessDataStore.kt:76)
at androidx.datastore.core.SingleProcessDataStore$actor$3.invokeSuspend (SingleProcessDataStore.kt:239)
at androidx.datastore.core.SingleProcessDataStore$actor$3.invoke (SingleProcessDataStore.kt)
at androidx.datastore.core.SingleProcessDataStore$actor$3.invoke (SingleProcessDataStore.kt)
at androidx.datastore.core.SimpleActor$offer$2.invokeSuspend (SimpleActor.kt:122)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run (DispatchedTask.kt:106)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely (CoroutineScheduler.kt:570)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask (CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker (CoroutineScheduler.kt:677)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run (CoroutineScheduler.kt:664)
Caused by java.security.GeneralSecurityException: decryption failed
at com.google.crypto.tink.daead.DeterministicAeadWrapper$WrappedDeterministicAead.decryptDeterministically (DeterministicAeadWrapper.java:90)
at androidx.security.crypto.EncryptedSharedPreferences.decryptKey (EncryptedSharedPreferences.java:601)
And here is how we do the migration:
@Singleton
@Provides
fun providePreferencesDataStore(@ApplicationContext appContext: Context): DataStore<Preferences> {
return PreferenceDataStoreFactory.create(
migrations = listOf(
SharedPreferencesMigration(
produceSharedPreferences = {
try {
val mainKey = MasterKey.Builder(appContext)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()
EncryptedSharedPreferences.create(
appContext,
"data",
mainKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
} catch (e: Exception) {
appContext.getSharedPreferences("data", Context.MODE_PRIVATE)
}
}
)
),
scope = CoroutineScope(Dispatchers.Default + SupervisorJob()), // Dispatchers.IO has the same problem
produceFile = { appContext.preferencesDataStoreFile("data2") }
)
}
is...@google.com <is...@google.com>
[Deleted User] <[Deleted User]> #109
implementation "androidx.security:security-crypto:1.1.0-alpha05"
Our some users are likely getting this below issue
Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{package.splash.SplashActivity}: ne.a0: Protocol message contained an invalid tag (zero).
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4166)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4312)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2571)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8741)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
And it caused by:
Caused by ne.a0: Protocol message contained an invalid tag (zero).
at com.google.crypto.tink.shaded.protobuf.ArrayDecoders.decodeUnknownField(ArrayDecoders.java:34)
at com.google.crypto.tink.shaded.protobuf.MessageSchema.parseProto3Message(MessageSchema.java:8)
at com.google.crypto.tink.shaded.protobuf.MessageSchema.mergeFrom(MessageSchema.java:4)
at com.google.crypto.tink.shaded.protobuf.ArrayDecoders.decodeMessageField(ArrayDecoders.java:28)
at com.google.crypto.tink.shaded.protobuf.ArrayDecoders.decodeMessageList(ArrayDecoders.java)
at com.google.crypto.tink.shaded.protobuf.MessageSchema.parseProto3Message(MessageSchema.java:8)
at com.google.crypto.tink.shaded.protobuf.MessageSchema.mergeFrom(MessageSchema.java:4)
at com.google.crypto.tink.shaded.protobuf.GeneratedMessageLite.parsePartialFrom(GeneratedMessageLite.java:5)
at com.google.crypto.tink.shaded.protobuf.GeneratedMessageLite.parseFrom(GeneratedMessageLite.java:5)
at com.google.crypto.tink.proto.Keyset.parseFrom(Keyset.java:2)
at com.google.crypto.tink.integration.android.SharedPrefKeysetReader.read(SharedPrefKeysetReader.java:2)
at com.google.crypto.tink.CleartextKeysetHandle.read(CleartextKeysetHandle.java:2)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.read(AndroidKeysetManager.java:2)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.readOrGenerateNewKeyset(AndroidKeysetManager.java:2)
at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.build(AndroidKeysetManager.java:11)
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:14)
at androidx.security.crypto.EncryptedSharedPreferences.create(EncryptedSharedPreferences.java:14)
at package.data.storage.BaseEncryptedSharedPreferences.<init>(BaseEncryptedSharedPreferences.java:14)
at package.data.storage.UserSharedPreferences.<init>(UserSharedPreferences.java:2)
at package.di.module.ApplicationModule.provideUserSharedPreferences(ApplicationModule.java:22)
at package.di.module.ApplicationModule_ProvideUserSharedPreferencesFactory.provideUserSharedPreferences(ApplicationModule_ProvideUserSharedPreferencesFactory.java:22)
at package.di.module.ApplicationModule_ProvideUserSharedPreferencesFactory.get(ApplicationModule_ProvideUserSharedPreferencesFactory.java:22)
at package.di.module.ApplicationModule_ProvideUserSharedPreferencesFactory.get(ApplicationModule_ProvideUserSharedPreferencesFactory.java:22)
at package.di.module.ApplicationModule_ProvideAppSharedPreferencesFactory.get$bridge(ApplicationModule_ProvideAppSharedPreferencesFactory.java:22)
at dagger.internal.DoubleCheck.get(DoubleCheck.java:13)
at package.di.DaggerApplicationComponent$SplashActivitySubcomponentImpl.injectSplashActivity(DaggerApplicationComponent.java:6)
at package.di.DaggerApplicationComponent$SplashActivitySubcomponentImpl.inject(DaggerApplicationComponent.java:6)
at package.di.DaggerApplicationComponent$SplashActivitySubcomponentImpl.inject(DaggerApplicationComponent.java:6)
at dagger.android.DispatchingAndroidInjector.maybeInject(DispatchingAndroidInjector.java:1)
at dagger.android.DispatchingAndroidInjector.inject(DispatchingAndroidInjector.java:1)
at dagger.android.AndroidInjection.inject(AndroidInjection.java:2)
at dagger.android.AndroidInjection.inject(AndroidInjection.java:2)
at dagger.android.support.DaggerAppCompatActivity.onCreate(DaggerAppCompatActivity.java:2)
at package.presentation.base.BaseActivity.onCreate(BaseActivity.java)
at package.presentation.splash.SplashActivity.onCreate(SplashActivity.java)
at android.app.Activity.performCreate(Activity.java:8578)
at android.app.Activity.performCreate(Activity.java:8557)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1384)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4147)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4312)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2571)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8741)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
Please let me know what is the solution.
ow...@gmail.com <ow...@gmail.com> #110
The issue lies specifically with the getAll()
method; no other methods see the decryption error. Beyond that, we can't diagnose further.
tu...@gmail.com <tu...@gmail.com> #111
pa...@etnetera.cz <pa...@etnetera.cz> #112
Did anyone try the new androidx.security:security-crypto:1.1.0-alpha06
that uses com.google.crypto.tink:tink-android:1.8.0
? Does this include the java.lang.SecurityException: Could not decrypt key. decryption failed
fix?
ia...@google.com <ia...@google.com> #113
Hi everyone.
Could you try using the latest library version 1.1.0-alpha06
? On our end we are able to check the error is no longer appearing.
If you still face this issue, could you please provide us with stack traces and error codes?
Thank you!
ch...@q42.nl <ch...@q42.nl> #114
Still occurs here on 1.1.0-alpha6
:
Caused by java.lang.SecurityException: Could not decrypt value. decryption failed
at androidx.security.crypto.EncryptedSharedPreferences.getDecryptedObject(EncryptedSharedPreferences.java:296)
at androidx.security.crypto.EncryptedSharedPreferences.getString(EncryptedSharedPreferences.java)
Caused by java.security.GeneralSecurityException: decryption failed
at com.google.crypto.tink.aead.AeadWrapper$WrappedAead.decrypt(AeadWrapper.java:133)
at androidx.security.crypto.EncryptedSharedPreferences.b(EncryptedSharedPreferences.java:42)
at androidx.security.crypto.EncryptedSharedPreferences.getString(EncryptedSharedPreferences.java)
hr...@gmail.com <hr...@gmail.com> #115
at androidx.security.crypto.EncryptedSharedPreferences.decryptKey(EncryptedSharedPreferences.java:631)
at androidx.security.crypto.EncryptedSharedPreferences.getAll(EncryptedSharedPreferences.java:416)
at com.example.data.provider.local.shared_pref.core.datastore.PrefsDataStoreMigration.migrate(PrefsDataStoreMigration.kt:30)
at com.example.data.provider.local.shared_pref.core.datastore.PrefsDataStoreMigration.migrate(PrefsDataStoreMigration.kt:15)
at androidx.datastore.core.DataMigrationInitializer$Companion$runMigrations$2.invokeSuspend(DataMigrationInitializer.kt:46)
at androidx.datastore.core.DataMigrationInitializer$Companion$runMigrations$2.invoke(Unknown Source:8)
at androidx.datastore.core.DataMigrationInitializer$Companion$runMigrations$2.invoke(Unknown Source:2)
at androidx.datastore.core.SingleProcessDataStore$readAndInit$api$1.updateData(SingleProcessDataStore.kt:337)
at androidx.datastore.core.DataMigrationInitializer$Companion.runMigrations(DataMigrationInitializer.kt:42)
at androidx.datastore.core.DataMigrationInitializer$Companion.access$runMigrations(DataMigrationInitializer.kt:23)
at androidx.datastore.core.DataMigrationInitializer$Companion$getInitializer$1.invokeSuspend(DataMigrationInitializer.kt:33)
at androidx.datastore.core.DataMigrationInitializer$Companion$getInitializer$1.invoke(Unknown Source:8)
at androidx.datastore.core.DataMigrationInitializer$Companion$getInitializer$1.invoke(Unknown Source:4)
at androidx.datastore.core.SingleProcessDataStore.readAndInit(SingleProcessDataStore.kt:348)
at androidx.datastore.core.SingleProcessDataStore.readAndInitOrPropagateFailure(SingleProcessDataStore.kt:311)
at androidx.datastore.core.SingleProcessDataStore.handleRead(SingleProcessDataStore.kt:261)
at androidx.datastore.core.SingleProcessDataStore.access$handleRead(SingleProcessDataStore.kt:76)
at androidx.datastore.core.SingleProcessDataStore$actor$3.invokeSuspend(SingleProcessDataStore.kt:239)
at androidx.datastore.core.SingleProcessDataStore$actor$3.invoke(Unknown Source:8)
at androidx.datastore.core.SingleProcessDataStore$actor$3.invoke(Unknown Source:4)
at androidx.datastore.core.SimpleActor$offer$2.invokeSuspend(SimpleActor.kt:122)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
Caused by: java.security.GeneralSecurityException: decryption failed
at com.google.crypto.tink.daead.DeterministicAeadWrapper$WrappedDeterministicAead.decryptDeterministically(DeterministicAeadWrapper.java:121)
at androidx.security.crypto.EncryptedSharedPreferences.decryptKey(EncryptedSharedPreferences.java:622)
at androidx.security.crypto.EncryptedSharedPreferences.getAll(EncryptedSharedPreferences.java:416)
at com.example.data.provider.local.shared_pref.core.datastore.PrefsDataStoreMigration.migrate(PrefsDataStoreMigration.kt:30)
at com.example.data.provider.local.shared_pref.core.datastore.PrefsDataStoreMigration.migrate(PrefsDataStoreMigration.kt:15)
at androidx.datastore.core.DataMigrationInitializer$Companion$runMigrations$2.invokeSuspend(DataMigrationInitializer.kt:46)
at androidx.datastore.core.DataMigrationInitializer$Companion$runMigrations$2.invoke(Unknown Source:8)
at androidx.datastore.core.DataMigrationInitializer$Companion$runMigrations$2.invoke(Unknown Source:2)
at androidx.datastore.core.SingleProcessDataStore$readAndInit$api$1.updateData(SingleProcessDataStore.kt:337)
at androidx.datastore.core.DataMigrationInitializer$Companion.runMigrations(DataMigrationInitializer.kt:42)
at androidx.datastore.core.DataMigrationInitializer$Companion.access$runMigrations(DataMigrationInitializer.kt:23)
at androidx.datastore.core.DataMigrationInitializer$Companion$getInitializer$1.invokeSuspend(DataMigrationInitializer.kt:33)
at androidx.datastore.core.DataMigrationInitializer$Companion$getInitializer$1.invoke(Unknown Source:8)
at androidx.datastore.core.DataMigrationInitializer$Companion$getInitializer$1.invoke(Unknown Source:4)
at androidx.datastore.core.SingleProcessDataStore.readAndInit(SingleProcessDataStore.kt:348)
at androidx.datastore.core.SingleProcessDataStore.readAndInitOrPropagateFailure(SingleProcessDataStore.kt:311)
at androidx.datastore.core.SingleProcessDataStore.handleRead(SingleProcessDataStore.kt:261)
at androidx.datastore.core.SingleProcessDataStore.access$handleRead(SingleProcessDataStore.kt:76)
at androidx.datastore.core.SingleProcessDataStore$actor$3.invokeSuspend(SingleProcessDataStore.kt:239)
at androidx.datastore.core.SingleProcessDataStore$actor$3.invoke(Unknown Source:8)
at androidx.datastore.core.SingleProcessDataStore$actor$3.invoke(Unknown Source:4)
at androidx.datastore.core.SimpleActor$offer$2.invokeSuspend(SimpleActor.kt:122)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664) ~~~
version: 1.1.0-alpha6
every time when I try to do migration from encryptedShared prefs to DataStore. The issue in getAll() function.
pa...@etnetera.cz <pa...@etnetera.cz> #116
It seems that the version 1.1.0-alpha06
didn’t fix this.
Now we have the following error. Probably the exception description was changed.
Caused by android.security.KeyStoreException: Memory allocation failed (internal Keystore code: -41 message: In generate_key.
Caused by:
0: While generating Key without explicit attestation key.
1: Error::Km(ErrorCode(-41)))
at android.security.KeyStore2.getKeyStoreException(KeyStore2.java:369)
at android.security.KeyStoreSecurityLevel.handleExceptions(KeyStoreSecurityLevel.java:57)
at android.security.KeyStoreSecurityLevel.generateKey(KeyStoreSecurityLevel.java:145)
at android.security.keystore2.AndroidKeyStoreKeyGeneratorSpi.engineGenerateKey(AndroidKeyStoreKeyGeneratorSpi.java:400)
at javax.crypto.KeyGenerator.generateKey(KeyGenerator.java:612)
at androidx.security.crypto.MasterKeys.generateKey(MasterKeys.java:149)
at androidx.security.crypto.MasterKeys.getOrCreate(MasterKeys.java:149)
at androidx.security.crypto.MasterKey$Builder$Api23Impl.build(MasterKey.java:149)
at androidx.security.crypto.MasterKey$Builder.build(MasterKey.java:149)
sm...@gmail.com <sm...@gmail.com> #117
xa...@dxb-tech.com <xa...@dxb-tech.com> #118
pa...@etnetera.cz <pa...@etnetera.cz> #119
I can confirm that the version 1.1.0-alpha06 didn’t fix this issue. We still have logs about this in Crashlytics.
pa...@etnetera.cz <pa...@etnetera.cz> #120
Dear Google team, do you have any update? Thanks.
sa...@supremetech.vn <sa...@supremetech.vn> #121
dm...@fiveflamesmobile.com <dm...@fiveflamesmobile.com> #122
ho...@gmail.com <ho...@gmail.com> #123
ho...@gmail.com <ho...@gmail.com> #124
downgrade to stable version or use "try catch" with code
Any solution that can end this problem?
Description
Component used: androidx.security:security-crypto:1.0.0-rc02
I haven't been able to repro these crashes, but I get lots of reports about them on Crashlytics ever since updating to 1.0.0-rc02
Crash #1 - Pixel 2; Android 10
Crash #2 - LG G7 ThinQ; Android 9
Crash #3 - LG G7 ThinQ; Android 9
Usage:
LogoutHelperImpl
Auth