Search code examples
androidpop3accountmanageractivesyncandroid-security

How to store user/password in android?


I am trying to create a simple app which connects to a mail server and retrieves emails periodically. I have read about AccountManager (http://developer.android.com/reference/android/.../AccountManager.html) and an excellent article on how to code a similar stuff (http://blog.udinic.com/2013/04/24/write-your-own-android-authenticator/).

In my understanding, this solution provides a way to work through Authentication Tokens that are returned by a server. However, in the case of mail servers like POP3 and Exchange Active Sync we need to provide username and password everytime we talk with them and auth token are of limited use.

Is there a way to securely store the username and password for this scenario?


Solution

  • Note that the AccountManager is not secured by any encryption method by default. The passwords there are stored in plain text.

    In general, storing sensitive data locally on an Android device is always at risk of being compromised. However, there are a few options available that can lessen your risk by making it more difficult for hackers to extract an application's sensitive data. Once you've encrypted your data, a common problem is that you then need a way to hide your encryption key from plain sight. Android's Keystore system can help with that.

    The Android Keystore system lets you store private keys in a container to make it more difficult to extract from the device. Once keys are in the keystore, they can be used for cryptographic operations with the private key material remaining non-exportable.

    I recommend checking out Ophio's Secure-Preferences library. The library provides an abstraction to obfuscating your data before storing it in SharedPreferences, and a KeyStoreKeyGenerator for encrypting your encryption key. Saving a user's password locally might look something like this:

    private static void stashPassword(Application application, String password) {
        String secretKey = null;
        try {
            secretKey = KeyStoreKeyGenerator.get(application, "KeyFilename")
                            .loadOrGenerateKeys();
        } catch (Exception exception) {
            // handle error
        }
    
        SharedPreferences preferences = new ObscuredPreferencesBuilder()
                .setApplication(application)
                .obfuscateValue(true)
                .obfuscateKey(true)
                .setSharePrefFileName(PREFERENCES_NAME)
                .setSecret(secretKey)
                .createSharedPrefs();
        preferences.edit().putString(KEY_PASSWORD, password).apply();
    }
    

    Take a look at this article for more information on securing the information you save in SharedPreferences.