How to store credentials on Android

There is a lot of discussion going on how to store credentials on the Android platform. What I’m going to discuss is focused on the Android platform, but you’ll notice that most of the things can be applied to all mobile plattforms. There are some differences, e.g. that you should use the much more evolved secure keystore of the iOS. There will be a keychain in Android 4.0. But of course you can screw up the secure storage on all platforms or even examples of the vendor show you how to screw up.

Before you start storing credentials the most important question is:

  • Do I really want to store that data and why?

Before you simply answer “yes”, consider the following:

  • Do you want to authenticate the user inside the app to check if he is allowed to access the app and other data?
    • Then use a secure cryptographic hash function (e.g. SHA-2). Use a salt which is long enough and randomly generated on the fly. You can store the salt in plain along with the generated hash. Use multiple hashing rounds (e.g. 10’000).
    • Don’t forget to check in every Activity that the user is already authenticated, because Activities can be invoked directly.
  • Do you want to authenticate the user against a server?
    • Before I go back to how you should store the credentials: Please use a secure channel to the server. One possibility is to use SSL (e.g. a HTTPS connection), but make sure you check the server certificate. Another possibility is to include a public key and have the corresponding private key on the server (actually I like this version even better, because you don’t have to trust hackable CA root companies).
    • Change the server side. Talk to your customer if you are developing an app for someone else, it’s not a big deal to change something on the server side. Try to store a session token instead of the password. Even increasing the expiry time for sessions is better than storing passwords on the client. Only increase it if the request is coming from the Android app, but not for all clients (like standard browser authentication).
    • If your really can’t change the server side and you can not use a token, you have a problem. Whatever you are doing from now, you have to store the password in reversable form, but the client isn’t a good option for that. Attackers equipped with root exploits and reverse engineering skills will always be able to get that password from somewhere (most of the time from the code or the filesystem). Consider that people often reuse passwords, which is a bad habit and if the password for your application is extracted, there might be other services that have to suffer from the laziness of the user.
      • There are several ways of how you could try to protect the credentials, but again, they’re all useless against a sophisticated attacker: E.g. encryption (key in the source code) and good obfuscation (some are just useless). EDIT: With the new Android KeyChain you are even better off if you have a hardware-backed storage on the device. Simply use the KeyChain to store a private key that you use to encrypt the password. The password can only be decrypted when the attacker is in the posession of the device, as he can not extract the private key from the device. Well of course he can extract the key, but root permissions are not sufficient and it means messing with the hardware (which is very expensive).
      • At least tell the user how the credentials are stored, why it could be a problem and what they can do to be protected (e.g. disable “remember password”).
      • Don’t screw up and write the password somewhere to the logs…

2 thoughts on “How to store credentials on Android

  1. Hi Mr Floyd.
    I know this is a pretty old blog post.
    But I was actually wondering the same question that you are trying to address here in this post.

    Do you know of any improvements on this topic?

    Regards

  2. Hi,

    No, I guess it’s still the same problem (although I haven’t actually searched for the newest Android features). Some application require the user to type in a PIN code, which is then used to derive a key (PBKDF2). With this key you can store passwords encrypted on the file system. This is actually just another trade-off: Instead of typing in the password, the user only has to enter the PIN. But because PINs are usually pretty weak (only numbers, mostly 4-6 digits) security is still lowered. But still better than storing passwords in plain. At least apps should give the user the option to use such a PIN.

    I guess it is best if you use the hardware-backed KeyChain.

    Best regards,
    floyd

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.