Detecting type of error when SecureStore.getItemAsync() rejects the promise

After fully uninstalling and reinstalling a standalone expo app, I started seeing this:

08-14 23:57:54.153  6475  6564 W SecureStoreModule:
08-14 23:57:54.153  6475  6564 W SecureStoreModule: javax.crypto.AEADBadTagException
08-14 23:57:54.153  6475  6564 W SecureStoreModule:     at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:517)
08-14 23:57:54.153  6475  6564 W SecureStoreModule:     at javax.crypto.Cipher.doFinal(Cipher.java:1741)
08-14 23:57:54.153  6475  6564 W SecureStoreModule:     at abi28_0_0.host.exp.exponent.modules.api.SecureStoreModule$AESEncrypter.decryptItem(SecureStoreModule.java:452)
08-14 23:57:54.153  6475  6564 W SecureStoreModule:     at abi28_0_0.host.exp.exponent.modules.api.SecureStoreModule.readJSONEncodedItem(SecureStoreModule.java:207)
08-14 23:57:54.153  6475  6564 W SecureStoreModule:     at abi28_0_0.host.exp.exponent.modules.api.SecureStoreModule.getItemImpl(SecureStoreModule.java:178)
08-14 23:57:54.153  6475  6564 W SecureStoreModule:     at abi28_0_0.host.exp.exponent.modules.api.SecureStoreModule.getValueWithKeyAsync(SecureStoreModule.java:166)
08-14 23:57:54.153  6475  6564 W SecureStoreModule:     at java.lang.reflect.Method.invoke(Native Method)
08-14 23:57:54.153  6475  6564 W SecureStoreModule:     at abi28_0_0.com.facebook.react.bridge.JavaMethodWrapper.invoke(JavaMethodWrapper.java:372)
08-14 23:57:54.153  6475  6564 W SecureStoreModule:     at abi28_0_0.com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:160)
08-14 23:57:54.153  6475  6564 W SecureStoreModule:     at abi28_0_0.com.facebook.react.bridge.queue.NativeRunnable.run(Native Method)
08-14 23:57:54.153  6475  6564 W SecureStoreModule:     at android.os.Handler.handleCallback(Handler.java:790)
08-14 23:57:54.153  6475  6564 W SecureStoreModule:     at android.os.Handler.dispatchMessage(Handler.java:99)
08-14 23:57:54.153  6475  6564 W SecureStoreModule:     at abi28_0_0.com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:29)
08-14 23:57:54.153  6475  6564 W SecureStoreModule:     at android.os.Looper.loop(Looper.java:164)
08-14 23:57:54.153  6475  6564 W SecureStoreModule:     at abi28_0_0.com.facebook.react.bridge.queue.MessageQueueThreadImpl$3.run(MessageQueueThreadImpl.java:192)
08-14 23:57:54.153  6475  6564 W SecureStoreModule:     at java.lang.Thread.run(Thread.java:764)
08-14 23:57:54.153  6475  6564 W SecureStoreModule: Caused by: android.security.KeyStoreException: Signature/MAC verification failed
08-14 23:57:54.153  6475  6564 W SecureStoreModule:     at android.security.KeyStore.getKeyStoreException(KeyStore.java:697)
08-14 23:57:54.153  6475  6564 W SecureStoreModule:     at android.security.keystore.KeyStoreCryptoOperationChunkedStreamer.doFinal(KeyStoreCryptoOperationChunkedStreamer.java:224)
08-14 23:57:54.153  6475  6564 W SecureStoreModule:     at android.security.keystore.AndroidKeyStoreAuthenticatedAESCipherSpi$BufferAllOutputUntilDoFinalStreamer.doFinal(AndroidKeyStoreAuthenticatedAESCipherSpi.java:373)
08-14 23:57:54.153  6475  6564 W SecureStoreModule:     at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:506)
08-14 23:57:54.153  6475  6564 W SecureStoreModule:     ... 15 more

I was wondering if I can figure out the different type of errors thrown by Expo’s SecureStore module in a reliable way. I want to know if the error is transient or not so that I can handle it correctly.

Basically, I think that sometimes an error would be thrown if the device is locked and my code somehow ran in the background and tried to access a secure value which requires the user to have unlocked the device. This is a transient error and my app should retry later.

However, this error I got now is due to the app being uninstalled and reinstalled. The old key the app used to decode content is, I assume, irrecoverable. So the error is permanent and my app must know that it should treat that error as if the key doesn’t exist. This error will never be recovered from by the user unlocking the screen—the app may even be foregrounded and the user’s keystore fully accessible.

The documentation only seems to say that the promise returned by SecureStore.getItemAsync() will be rejected if there is an error. Based on the source code , it looks like I might get the same type of error if expo fails to get the key from the keystore. Or will I get a different error?

Can there be documentation describing how to detect the different types of errors?

Thanks.

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.