1

My app is currently using

sp = PreferenceManager.getDefaultSharedPreferences(ctx);

to get the sharedpreference object. Due to some security requirements, now I need to upgrade this to use EncryptedSharedPreference provided in the android jetpack library.

What happens here is when I use EncryptedSharedPreference object I loose all the data stored in normal shared preference file.
How can I get all my data on the EncryptedSharedPreferences.

Ichigo Kurosaki
  • 3,765
  • 8
  • 41
  • 56
  • This may help you : https://stackoverflow.com/questions/30148729/how-to-secure-android-shared-preferences – haresh Jan 02 '20 at 09:58
  • That is how I have implemented it now, but how can I upgrade for existing without losing the existing data. – Ritu Srivastava Jan 03 '20 at 10:22
  • How can it be? See https://medium.com/att-israel/how-to-migrate-to-encrypted-shared-preferences-cc4105c03518. If use the same file for `SharedPreference` and `EncryptedSharedPreference`, new data will be accumulated, not clearing previous. – CoolMind Mar 22 '21 at 14:32

1 Answers1

2

Answer:

My migration looks like this:

fun migrate() {
    val oldPreferences = PreferenceManager.getDefaultSharedPreferences(context)
    val newPreferences =  EncryptedSharedPreferences.create(...)
    with(newPreferences.edit()) {
        oldPreferences.all.forEach { (key, value) ->
            when (value) {
                is Boolean -> putBoolean(key, value)
                is Float -> putFloat(key, value)
                is String -> putString(key, value)
                is Int -> putInt(key, value)
                is Long -> putLong(key, value)
                is Set<*> -> putStringSet(key, value.map { it.toString() }.toSet())
                else -> throw IllegalStateException("unsupported type for shared preferences migration")
            }
        }
        apply()
    }
    oldPreferences.edit().clear().apply()
}

It is possible to do this without creating new shared preferences file, but why would you...

Explanation:

Any shared preferences are stored in an .xml file. You can find the file and read it, so it's not that hard to see what is happening with it.

I've tried to use EncryptedSharedPreferences with existing file and old values remained unencrypted. And EncryptedSharedPreferences are not able to access old values now.

EncryptedSharedPreferences are not encrypting the file. They encrypt keys and values separately, so your preferences.xml file might look like this:

<map>
    <string name="__androidx_security_crypto_encrypted_prefs_key_keyset__">12a9018b0938...</string>
    <string name="AWNywuPwU...">ARu2fgn5N7wV...</string>
    <string name="__androidx_security_crypto_encrypted_prefs_value_keyset__">1288018cc6...</string>
</map>

This means you cannot run some oneliner to encrypt existing file. So I believe the only way is to make your own migration as shown in answer.

Hope it helps

VizGhar
  • 3,036
  • 1
  • 25
  • 38