cioccarellia / ksprefs

Kotlin SharedPreferences wrapper & cryptographic android library.
https://cioccarellia.github.io/ksprefs/
Apache License 2.0
228 stars 22 forks source link

Experiencing bugs around pull #37

Closed brookmg closed 3 years ago

brookmg commented 3 years ago

The basic stacktrace is as following

com.cioccarellia.ksprefs.exceptions.EngineException: 
 at com.cioccarellia.ksprefs.exceptions.EngineException$Companion.convertFrom(EngineException.kt:34)
 at com.cioccarellia.ksprefs.extensions.ExceptionExtsKt.getOrThrowException(ExceptionExts.kt:23)
 at com.cioccarellia.ksprefs.internal.SafeRun$DefaultImpls.runSafely(SafeRun.kt:26)
 at com.cioccarellia.ksprefs.engines.base.Engine.runSafely(Engine.kt:25)
 at com.cioccarellia.ksprefs.internal.SafeRun$DefaultImpls.runSafely$default(SafeRun.kt:24)
 at com.cioccarellia.ksprefs.engines.model.keystore.AesKeyStoreEngine.decrypt(AesKeyStoreEngine.kt:77)
 at com.cioccarellia.ksprefs.engines.model.keystore.AesKeyStoreEngine.integrate-Wp7FQgo(AesKeyStoreEngine.kt:51)
 at com.cioccarellia.ksprefs.enclosure.KspEnclosure.read$library(KspEnclosure.kt:111)
 at com.cioccarellia.ksprefs.dispatcher.KspDispatcher.pull(KspDispatcher.kt:73)
 at com.cioccarellia.ksprefs.KsPrefs.pull(KsPrefs.kt:152)
 at ---------------.ui.fragment.HomeFragment.onViewCreated(HomeFragment.kt:119)
 at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:332)
 at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1199)
 at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2236)
 at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2009)
 at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1965)
 at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1861)
 at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
 at android.os.Handler.handleCallback(Handler.java:883)
 at android.os.Handler.dispatchMessage(Handler.java:100)
 at android.os.Looper.loop(Looper.java:237)
 at android.app.ActivityThread.main(ActivityThread.java:7948)
 at java.lang.reflect.Method.invoke(Native Method)
 at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
Caused by: javax.crypto.IllegalBlockSizeException
 at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:519)
 at javax.crypto.Cipher.doFinal(Cipher.java:2055)
 at com.cioccarellia.ksprefs.engines.model.keystore.AesKeyStoreEngine$decrypt$1.invoke(AesKeyStoreEngine.kt:78)
 at com.cioccarellia.ksprefs.engines.model.keystore.AesKeyStoreEngine$decrypt$1.invoke(AesKeyStoreEngine.kt:34)
 ... 23 more
Caused by: android.security.KeyStoreException: Invalid operation handle
 at android.security.KeyStore.getKeyStoreException(KeyStore.java:1550)
 at android.security.keystore.KeyStoreCryptoOperationChunkedStreamer.update(KeyStoreCryptoOperationChunkedStreamer.java:132)
 at android.security.keystore.KeyStoreCryptoOperationChunkedStreamer.doFinal(KeyStoreCryptoOperationChunkedStreamer.java:217)
 at android.security.keystore.AndroidKeyStoreAuthenticatedAESCipherSpi$BufferAllOutputUntilDoFinalStreamer.doFinal(AndroidKeyStoreAuthenticatedAESCipherSpi.java:373)
 at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:506)
 ... 26 more

My configuration at app start is:

val prefs by lazy {
    KsPrefs(appContext = instance) {
        encryptionType = EncryptionType.KeyStore("prefs")
        commitStrategy = CommitStrategy.COMMIT
    }
}
cioccarellia commented 3 years ago

Counl you provide more details about the software version / root status of your device?

brookmg commented 3 years ago

Sure,

KsPref = 2.2.5 Android = 10 ( 29 ) Root = false Device = Samsung Galaxy J6 ( But it also happened for other devices which I don't know the spec for )

More info on the stacktrace

Caused by javax.crypto.IllegalBlockSizeException
       at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:519)
       at javax.crypto.Cipher.doFinal(Cipher.java:2055)
       at com.cioccarellia.ksprefs.engines.model.keystore.AesKeyStoreEngine$decrypt$1.invoke(AesKeyStoreEngine.kt:78)
       at com.cioccarellia.ksprefs.engines.model.keystore.AesKeyStoreEngine$decrypt$1.invoke(AesKeyStoreEngine.kt:34)
       at com.cioccarellia.ksprefs.internal.SafeRun$DefaultImpls.runSafely(SafeRun.kt:26)
       at com.cioccarellia.ksprefs.engines.base.Engine.runSafely(Engine.kt:25)
       at com.cioccarellia.ksprefs.internal.SafeRun$DefaultImpls.runSafely$default(SafeRun.kt:24)
       at com.cioccarellia.ksprefs.engines.model.keystore.AesKeyStoreEngine.decrypt(AesKeyStoreEngine.kt:77)
       at com.cioccarellia.ksprefs.engines.model.keystore.AesKeyStoreEngine.integrate-Wp7FQgo(AesKeyStoreEngine.kt:51)
       at com.cioccarellia.ksprefs.enclosure.KspEnclosure.read$library(KspEnclosure.kt:111)
       at com.cioccarellia.ksprefs.dispatcher.KspDispatcher.pull(KspDispatcher.kt:73)
       at com.cioccarellia.ksprefs.KsPrefs.pull(KsPrefs.kt:152)
       at -----------------.ui.fragment.HomeFragment.onViewCreated(HomeFragment.kt:119)
       at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:332)
       at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1199)
       at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2236)
       at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2009)
       at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1965)
       at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1861)
       at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
       at android.os.Handler.handleCallback(Handler.java:883)
       at android.os.Handler.dispatchMessage(Handler.java:100)
       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 android.security.KeyStoreException: Invalid operation handle
       at android.security.KeyStore.getKeyStoreException(KeyStore.java:1550)
       at android.security.keystore.KeyStoreCryptoOperationChunkedStreamer.update(KeyStoreCryptoOperationChunkedStreamer.java:132)
       at android.security.keystore.KeyStoreCryptoOperationChunkedStreamer.doFinal(KeyStoreCryptoOperationChunkedStreamer.java:217)
       at android.security.keystore.AndroidKeyStoreAuthenticatedAESCipherSpi$BufferAllOutputUntilDoFinalStreamer.doFinal(AndroidKeyStoreAuthenticatedAESCipherSpi.java:373)
       at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:506)
       at javax.crypto.Cipher.doFinal(Cipher.java:2055)
       at com.cioccarellia.ksprefs.engines.model.keystore.AesKeyStoreEngine$decrypt$1.invoke(AesKeyStoreEngine.kt:78)
       at com.cioccarellia.ksprefs.engines.model.keystore.AesKeyStoreEngine$decrypt$1.invoke(AesKeyStoreEngine.kt:34)
       at com.cioccarellia.ksprefs.internal.SafeRun$DefaultImpls.runSafely(SafeRun.kt:26)
       at com.cioccarellia.ksprefs.engines.base.Engine.runSafely(Engine.kt:25)
       at com.cioccarellia.ksprefs.internal.SafeRun$DefaultImpls.runSafely$default(SafeRun.kt:24)
       at com.cioccarellia.ksprefs.engines.model.keystore.AesKeyStoreEngine.decrypt(AesKeyStoreEngine.kt:77)
       at com.cioccarellia.ksprefs.engines.model.keystore.AesKeyStoreEngine.integrate-Wp7FQgo(AesKeyStoreEngine.kt:51)
       at com.cioccarellia.ksprefs.enclosure.KspEnclosure.read$library(KspEnclosure.kt:111)
       at com.cioccarellia.ksprefs.dispatcher.KspDispatcher.pull(KspDispatcher.kt:73)
       at com.cioccarellia.ksprefs.KsPrefs.pull(KsPrefs.kt:152)
       at -----------------.ui.fragment.HomeFragment.onViewCreated(HomeFragment.kt:119)
       at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:332)
       at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1199)
       at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2236)
       at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2009)
       at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1965)
       at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1861)
       at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
       at android.os.Handler.handleCallback(Handler.java:883)
       at android.os.Handler.dispatchMessage(Handler.java:100)
       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)

I'm not exactly sure when this occurs. It happens in undeterministed pattern

cioccarellia commented 3 years ago

For the life of me I can't reproduce this. Will dig deeper as I have time, probably the issue resides in the ksprefs implementation of the android keystore mechanism, so a rewrite of AesKeyStoreEngine might get things going smoothly. I can advise to use AES-backed encryption until then, which is stable and significantly faster.

brookmg commented 3 years ago

Ya, I suspected that as well. Thanks for giving it a shot I will subscribe to this in case of any new development