Android: Is it a good idea to store Authentication Token in Shared Preferences?

24,721

Solution 1

In short, yes, that's a perfectly reasonable thing to do.

The best you can do on top of that is obfuscation only. If you keep the token in memory, a root user can peek into that. If you encrypt it, you have to store the encryption key on the device also or you won't be able to use the token… and the key can be stolen just as easily as the token.

If someone has root on the device, all bets are off. Don't optimize for that case. If your app is super-duper high security, don't allow it to run on rooted devices, or implement a remote-wipe functionality where the user can report their device stolen and you can invalidate the token on the server.

Android 4.3 introduced the Android Keystore. That purportedly provides a secure store for cryptographic keys. This could be used to store a key that's used to decrypt an encrypted token stored with traditional methods. However, the referenced link gives no mention of how a rooted device impacts the security of this.

UPDATE 2018: Most modern Android devices have hardware-backed keystores, via a trusted execution environment (TEE) provided by the SoC. This makes it impossible (see below) for hacker to obtain the keystore master key that would otherwise be needed to decrypt the keys you've stored in the Android Keystore.

Well, "impossible" is a strong word. It's better said as "infeasible". Meaning, you'd need something like an electron microscope to scan the bits fused into the SoC providing the TEE. If you are the type of person whose data warrants this sort of attention, you probably have bigger problems.

Solution 2

If there is concern that the token could be read from SharedPreferences, a good rule of thumb is to provide a certain level of obfuscation to the data being stored.

This response outlines a simple class to obfuscate SharedPreferences data: What is the most appropriate way to store user settings in Android application

Solution 3

There is an easier and quicker way to encrypt data now as there is an implementation of SharedPreferences that encrypts keys and values. You can use EncryptedSharedPreferences in Android JetPack Security.

Just add AndroidX Security into your build.gradle:

implementation 'androidx.security:security-crypto:1.0.0-rc01'

And you can use it like this:

String masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC);

SharedPreferences sharedPreferences = EncryptedSharedPreferences.create(
    "secret_shared_prefs",
    masterKeyAlias,
    context,
    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
);

// use the shared preferences and editor as you normally would
SharedPreferences.Editor editor = sharedPreferences.edit();

See more details: https://android-developers.googleblog.com/2020/02/data-encryption-on-android-with-jetpack.html

Official docs: https://developer.android.com/reference/androidx/security/crypto/EncryptedSharedPreferences

Share:
24,721
Eric Bergman
Author by

Eric Bergman

Updated on February 18, 2021

Comments

  • Eric Bergman
    Eric Bergman about 3 years

    I have an application that communicates with a server. When the user logins to the application an Authentication Token is crated on the server and stored in the SharedPreferences of the application and whenever the application requests data from a web service the authentication token is validated.

    My question is, is it secure to store the authentication token in the SharedPreferences? I'm asking because a user with root privileges can access the preferences, extract the token and use it.

    Is there anyway to have more security in that regard?