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

AEADBadTagException while connecting to TTP, after transferring app data #513

Open
wkol opened this issue Oct 14, 2024 · 0 comments
Open

Comments

@wkol
Copy link

wkol commented Oct 14, 2024

Summary

Hi, recently we started observing a larger amount of problems when connecting to TTP that lead to crashes with an exception:
KeyStoreException: Signature/MAC verification failed (internal Keystore code: -30 message: system/security/keystore2/src/operation.rs:850: KeystoreOperation::finish. After a brief research, I found out that this error is caused by an attempt to decrypt the shared preferences with an outdated key.

Such a case, I believe, can occur when an app that has the allowBackup manifest flag is set to true, and the user does a device-to-device restore, which restores the shared preferences, but since they were encrypted using another device keystore, they now cannot be decrypted.

The simplest solution would be to set the allowBackup flag to false, but since we would like to keep the backup feature, the other solution (which is advised by the Android documentation) is to explicitly exclude the specific shared prefs (in that case a list of what shared_prefs files should not be backed up will be needed).

Another solution would be to clear the app/SDK data after receiving this error which resolves the error, but this ideally require a method to reset all the SDK data (but it would be a nice addition since we sometimes experience other KeyStoreExceptions).

Code to reproduce

The 1:1 reproduction requires two devices, so to simulate such a case, we can just delete the asp_key (that leads to a mismatch between the key used to encrypt and the key used to decrypt) and try to connect to Tap to Pay:

KeyStore.getInstance("AndroidKeyStore").run { 
    load(null)
    deleteEntry("asp_key")
}

Android version

14/13 (does not matter)

Impacted devices (Android devices or readers)

Tap to Pay

SDK version

3.9.5

Other information

The whole stacktrace
java.lang.RuntimeException: Unable to bind to service com.stripe.cots.aidlservice.CotsService@b79208b with Intent { act= cmp=<package>/com.stripe.cots.aidlservice.CotsService }: javax.crypto.AEADBadTagException
 	at android.app.ActivityThread.handleBindService(ActivityThread.java:4696)
 	at android.app.ActivityThread.-$$Nest$mhandleBindService(Unknown Source:0)
 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2272)
 	at android.os.Handler.dispatchMessage(Handler.java:106)
 	at android.os.Looper.loopOnce(Looper.java:205)
 	at android.os.Looper.loop(Looper.java:294)
 	at android.app.ActivityThread.main(ActivityThread.java:8177)
 	at java.lang.reflect.Method.invoke(Native Method)
 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
 Caused by: javax.crypto.AEADBadTagException
 	at android.security.keystore2.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:626)
 	at javax.crypto.Cipher.doFinal(Cipher.java:2114)
 	at com.google.crypto.tink.integration.android.AndroidKeystoreAesGcm.decryptInternal(AndroidKeystoreAesGcm.java:118)
 	at com.google.crypto.tink.integration.android.AndroidKeystoreAesGcm.decrypt(AndroidKeystoreAesGcm.java:101)
 	at com.google.crypto.tink.KeysetHandle.decrypt(KeysetHandle.java:919)
 	at com.google.crypto.tink.KeysetHandle.readWithAssociatedData(KeysetHandle.java:804)
 	at com.google.crypto.tink.KeysetHandle.read(KeysetHandle.java:785)
 	at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.readMasterkeyDecryptAndParseKeyset(AndroidKeysetManager.java:381)
 	at com.google.crypto.tink.integration.android.AndroidKeysetManager$Builder.build(AndroidKeysetManager.java:297)
 	at java.lang.reflect.Method.invoke(Native Method)
 	at com.s.t.BillingV22436.ad_(:155)
 	at com.s.t.BillingV22436.ac_(:120)
 	at com.s.u.managingJ17450.As(:183)
 	at com.s.u.managingJ17450.<init>(:108)
 	at com.s.af.choiceF7628.Billing(:17)
 	at com.s.af.choiceF7628.Dashboard(:1)
 	at com.s.af.choiceF7628.As(:65354)
 	at com.s.af.complianceE24073.Dashboard(:2043)
 	at com.s.af.complianceE24073.As(:65353)
 	at com.s.af.complianceE24073.Connect(:35)
 	at com.s.af.complianceE24073.get(:11)
 	at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
 	at com.s.af.deploymentN2911.Connect(:40)
 	at com.s.af.deploymentN2911.get(:12)
 	at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
 	at com.s.u.accessoriesD1361.Build(:110)
 	at com.s.u.accessoriesD1361.get(:19)
 	at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
 	at com.s.af.ConnectV30425.Connect(:62)
 	at com.s.af.ConnectV30425.get(:17)
 	at com.s.s.BuildF9013.Dashboard(:43)
 	at com.s.s.BuildF9013.get(:14)
 	at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
 	at com.s.s.DashboardO28928.Billing(:38)
 	at com.s.s.DashboardO28928.get(:13)
 	at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
 	at com.s.s.BillingW21809.Connect(:43)
 	at com.s.s.BillingW21809.get(:14)
 	at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
 	at com.s.u.evenY23415$ConnectH22350.Connect(:764)
 	at com.stripe.cots.aidlservice.CotsService$DashboardA7632.invokeSuspend(:96)
 	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
 	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
 	at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:111)
 	at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:99)
 	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
 	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:811)
 	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:715)
 	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:702)
E  Caused by: android.security.KeyStoreException: Signature/MAC verification failed (internal Keystore code: -30 message: system/security/keystore2/src/operation.rs:850: KeystoreOperation::finish
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant