adorsys / secure-storage-android

Store strings & credentials securely encrypted on your device
Apache License 2.0
367 stars 58 forks source link

Exception when storing long Strings #28

Closed rodrixan closed 6 years ago

rodrixan commented 6 years ago

Hi there!

First of all, awesome job on the library, it really keeps the encrypting neat and simple. Good work!

Nevertheless, I'm facing the next issue: When a long string is gonna be stored, the library throws an Exception (see below for more info). It seems to happen when the string length is over 245 characters.

String string246Chars = "AciQ7fLfNGx1l5EivLMGIDtK33Q7P2PfXrqjbKJTdPzkdplrCSlf9LZdwwE2tKNgsvW3tLTnAlr9A5mF2CdNdZjFqJBtZDiAKph4SRsmhpJ94ZM7aXRYBb8KARzyYqYnTfbBkIG3UmRSCKEYrTAB34owTNKK1t7VYrsFrUIbbG4p6OI32Yby5ORVXhLmUAy32qwjMVw0UdLur6NXCcx5Sg0kxZvM6z47IKeSdsWitlsVtHIH8TKOGP";

SecurePreferences.setValue("ALIAS", string246Chars);

java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
    Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 
Caused by: de.adorsys.android.securestoragelibrary.SecureStorageException: Problem during Encryption

As long as I've not been able to see anything related to this in the documentation, Is it supposed to work like that?

Furthermore, if any user wants to store a token from backend or something similar, what can he do as an alternative?

Thanks in advice, and greetings,

Rodri

oikmar commented 6 years ago

i think it throwing a IllegalBlockSizeException for long string values.

drilonrecica commented 6 years ago

Hi @rodrixan & @oikmar ,

We are aware of this limitation to max 245 characters. That is a flaw of Assymmetric Encryption and unfortunately we can't do much about that.

We are currently working on an implementation of secure storage that uses Symmetric Encryption which does not have these kind of limitations.

gotev commented 6 years ago

Came across the same problem and done a workaround.
Until the new release is ready, you can use this:

object SecurePreferencesHelper {
    private const val chunkSize = 240

    private fun getNumberOfChunksKey(key: String) = "${key}_numberOfChunks"

    fun setLongStringValue(key: String, value: String) {
        val chunks = value.chunked(chunkSize)

        SecurePreferences.setValue(getNumberOfChunksKey(key), chunks.size)

        chunks.forEachIndexed { index, chunk ->
            SecurePreferences.setValue("$key$index", chunk)
        }
    }

    fun getLongStringValue(key: String): String? {
        val numberOfChunks = SecurePreferences.getIntValue(getNumberOfChunksKey(key), 0)

        if (numberOfChunks == 0) {
            return null
        }

        return (0 until numberOfChunks)
                .map { index ->
                    val string = SecurePreferences.getStringValue("$key$index", null) ?: run {
                        return null
                    }

                    string
                }.reduce { accumulator, chunk -> accumulator + chunk }
    }

    fun removeLongStringValue(key: String) {
        val numberOfChunks = SecurePreferences.getIntValue(getNumberOfChunksKey(key), 0)

        (0 until numberOfChunks).map { SecurePreferences.removeValue("$key$it") }
        SecurePreferences.removeValue(getNumberOfChunksKey(key))
    }

    fun containsLongStringValue(key: String): Boolean {
        return SecurePreferences.contains(getNumberOfChunksKey(key))
    }
}
ben-p-commits commented 6 years ago

Was about to abandon the library due to this limit- happy to see a workaround + plans for having this in the next release. Clever!

kibotu commented 5 years ago

i don't think this works any longer :/

kibotu commented 5 years ago

i've updated the workaround against 1.2.2 https://github.com/exozet/AndroidCore/blob/master/core/src/main/java/com/exozet/android/core/storage/SecurePreferencesLongString.kt

also relevant:

https://github.com/exozet/AndroidCore/blob/master/core/src/main/java/com/exozet/android/core/storage/SecureStorageDelegate.kt

usage:

var password by secureStorage("password", "")
password = jwt