180

If I want to store the username and password to be used inside an Android application, what is the best way to do it? Is it through the preferences screen (but what if the user misses this?), or pop up a dialog box and ask the user for the credentials? If so, I do have to maintain state for the application. How would I do this?

Legend
  • 104,480
  • 109
  • 255
  • 385
  • 4
    http://stackoverflow.com/a/786588/1166727 Check out what @RetoMeier (Tech Lead for Android Development at Google) has to say about this. – tony gil Jul 22 '12 at 15:02
  • 1
    If you are looking for safest way to store the credentials.Read this answer http://stackoverflow.com/a/20560574/730807 – Durai Amuthan.H Nov 27 '14 at 22:24
  • 3
    @Legend how u resolved your issue ? – Erum Feb 07 '15 at 10:10
  • @Legend, can you throw some light on saving pwd in prefs after encryption.. because I want my app to work without any internet then how do I get key ..(coz I cant store key on device) – eRaisedToX Aug 18 '17 at 16:52
  • You can use keystore for Api +18 .https://developer.android.com/training/articles/keystore – Nabzi May 27 '20 at 07:43

9 Answers9

120

Most Android and iPhone apps I have seen use an initial screen or dialog box to ask for credentials. I think it is cumbersome for the user to have to re-enter their name/password often, so storing that info makes sense from a usability perspective.

The advice from the (Android dev guide) is:

In general, we recommend minimizing the frequency of asking for user credentials -- to make phishing attacks more conspicuous, and less likely to be successful. Instead use an authorization token and refresh it.

Where possible, username and password should not be stored on the device. Instead, perform initial authentication using the username and password supplied by the user, and then use a short-lived, service-specific authorization token.

Using the AccountManger is the best option for storing credentials. The SampleSyncAdapter provides an example of how to use it.

If this is not an option to you for some reason, you can fall back to persisting credentials using the Preferences mechanism. Other applications won't be able to access your preferences, so the user's information is not easily exposed.

Community
  • 1
  • 1
Eric Levine
  • 13,196
  • 5
  • 46
  • 48
  • 41
    I would say it's risky to persist password information as is in preferences. On rooted phones it is possible to access the preferences file of an app. The least you can do is obfuscate the password. – Jayesh Dec 18 '09 at 18:15
  • 51
    If someone has your phone and is able to root it, there is not a whole lot you are going to be able to do to keep your data safe. Its not a bad idea to obfuscate the password, but it isn't really adding that much more protection. What is more important is that there are many layers of security already built into the OS. Of course, you don't want to do anything stupid to circumvent those measures. It is probably better to use a system like OAuth, and store a token on the device instead of the username and password. – Eric Levine Aug 11 '10 at 15:42
  • Also see this question [link](http://stackoverflow.com/questions/785973/what-is-the-most-appropriate-way-to-store-user-settings-in-android-application) – Diederik Feb 09 '11 at 09:14
  • 4
    If you use the `AccountManager` (as per my answer, and @Miguel's in a roundabout way) and somebody gets a hold of your GSM phone, they'll need to keep using your SIM to have access to your accounts, as it will invalidate stored credentials when the SIM changes. – Jon O Apr 04 '12 at 18:08
  • 3
    Account wiping on SIP change has been removed quite a while ago, because it makes little sense, especially for people who have more than one SIM. A better strategy if your phone is stolen is to go to your Google account page and revoke access for the particular device. – Nikolay Elenkov May 09 '13 at 01:32
  • 2
    *"Using the AccountManger is the best option for storing credentials."* **Why?** – Luc May 09 '14 at 22:02
  • @Luc it already handles storing authentication info for accounts and its gone through the AOSP development process. There's no need to duplicate that effort. – Eric Levine May 13 '14 at 01:27
  • AccountManager is only added in API 23. I am using min api version 19. What is the best solution for API 19? – Coder Aug 07 '16 at 05:30
  • 2
    @Coder According to the docs linked in my answer, AccountManager has been available since API 5 – Eric Levine Aug 08 '16 at 14:09
  • 1
    I thought storing things using AccountManager was not any safer? If the app does not access a web service or if the web service is a third party that does not generate tokens, what to do? – Myoch Jan 13 '18 at 12:17
9

You should use the Android AccountManager. It's purpose-built for this scenario. It's a little bit cumbersome but one of the things it does is invalidate the local credentials if the SIM card changes, so if somebody swipes your phone and throws a new SIM in it, your credentials won't be compromised.

This also gives the user a quick and easy way to access (and potentially delete) the stored credentials for any account they have on the device, all from one place.

SampleSyncAdapter (like @Miguel mentioned) is an example that makes use of stored account credentials.

Jon O
  • 6,267
  • 1
  • 41
  • 54
  • 3
    Where is it documented that AccountManager will "invalidate the local credentials if the SIM card changes"? – Eric Levine Apr 24 '12 at 02:19
  • It isn't that I'm aware of. However, it's something I've come to believe/accept/understand after some users of my app have had authentication issues following SIM swaps. – Jon O Apr 24 '12 at 05:24
  • 1
    I don't see it in the JavaDocs or AccountManager code. It sounds like a good feature, it would just be nice to verify it and understand the details. – Eric Levine Apr 24 '12 at 13:02
  • Give it a quick test; pull your SIM and try to auth over wifi with stored credentials. I would try it myself, but I'm on CDMA. – Jon O Apr 24 '12 at 15:23
  • 2
    According to @NikolayElenkov the invalidate on SIM card change feature has been removed. – ThomasW Feb 04 '14 at 02:08
  • 2
    @ThomasW do you have a citation for that? It would be great to get a definitive answer of some kind. – Jon O Feb 05 '14 at 21:07
8

I think the best way to secure your credential is to first think of storing the Password with encryption in the account.db file which couldn't be easily available in non rooted devices and in case of rooted device the hacker must need the key to decrypt it.

Other option is do all your authentication like the way Gmail is doing. after the first authentication with the Gmail server . you got the Auth Token that would be use in case of your password . that token would be store in plain text.this token could be false in case you change the password from Server.

the last option I'd recommend you to enable 2-Factor Authentication & create Device Specific Password for your device. After losing device, all you need is to disable that device.

Riz
  • 123
  • 1
  • 3
  • 2
    Can you post a source which says, that accounts.db is encrypted? Or do you say that the specific password should be encrypted? – Michał Klimczak Sep 26 '14 at 08:56
  • 1
    @Riz , where to store the key for encryption then...because my app works without Internet ,so cant get it from network – eRaisedToX Aug 18 '17 at 16:55
3

Take a look at What is the most appropriate way to store user settings in Android application if you're concerned about storing passwords as clear text in SharedPreferences.

Community
  • 1
  • 1
emmby
  • 95,927
  • 63
  • 178
  • 243
2

Take a look at this this post from android-developers, that might help increasing the security on the stored data in your Android app.

Using Cryptography to Store Credentials Safely

dwbrito
  • 4,738
  • 5
  • 28
  • 47
2

With the new (Android 6.0) fingerprint hardware and API you can do it as in this github sample application.

Zlatko
  • 1,145
  • 10
  • 19
  • 8
    The referenced sample project creates a key in the Android Key Store and uses it to create a cipher to encrypted the password. The encrypted password and cipher are stored as base64 encoded strings in the shared preferences. Upon successful fingerprint authentication, the secret key is retrieved from the Android Key Store and used with the decoded cipher to decrypt the decoded password. – mjwheat Apr 06 '16 at 15:07
  • @mjwheat this is so helpful to understand what's going on in the example. Thanks! One little typo: "...to decrypt the encoded password." – muetzenflo Aug 19 '16 at 09:31
2

You can also look at the SampleSyncAdapter sample from the SDK. It may help you.

Josh Lee
  • 149,877
  • 34
  • 253
  • 263
miguelv
  • 2,856
  • 1
  • 23
  • 22
2

These are ranked in order of difficulty to break your hidden info.

  1. Store in cleartext

  2. Store encrypted using a symmetric key

  3. Using the Android Keystore

  4. Store encrypted using asymmetric keys

source: Where is the best place to store a password in your Android app

The Keystore itself is encrypted using the user’s own lockscreen pin/password, hence, when the device screen is locked the Keystore is unavailable. Keep this in mind if you have a background service that could need to access your application secrets.

source: Simple use the Android Keystore to store passwords and other sensitive information

Dmytro Melnychuk
  • 1,569
  • 15
  • 19
1

The info at http://nelenkov.blogspot.com/2012/05/storing-application-secrets-in-androids.html is a fairly pragmatic, but "uses-hidden-android-apis" based approach. It's something to consider when you really can't get around storing credentials/passwords locally on the device.

I've also created a cleaned up gist of that idea at https://gist.github.com/kbsriram/5503519 which might be helpful.

kbs
  • 216
  • 2
  • 1