44

I want to store the password used for signing in a financial application that I am developing at a secure place. After doing some net surfing I found following options but each of them has certain drawback.

1) KeyChain.
Only available in OS version 4.

2) Shared Preferences.
It stores data in plain text even though if I encrypt the data then the encryption key can be compromised by decompiling the application code.

3) Access keystore daemon and store credentials in it.
(http://nelenkov.blogspot.com/2012/05/storing-application-secrets-in-androids.html) Requires another password to remember.

Please suggest me a better way to secure credential information in android application like IPhone KeyChain.

Robert
  • 39,162
  • 17
  • 99
  • 152
Noor
  • 603
  • 1
  • 6
  • 15
  • 2
    see http://stackoverflow.com/questions/1925486/android-storing-username-and-password – mjn Apr 07 '13 at 19:37

2 Answers2

18

The is no equivalent of iPhone's KeyChain in Android currently. If you want to keep something secret, don't store it on the device. Or at least, don't store the key/password it is encrypted with on the device. Simple as that.

Additionally:

1) Even on ICS, you cannot use the KeyChain directly to store application secrets (see blog post in 3))

2) This is only a problem for rooted phones, or if someone has physical access to the device.

3) It is a lot better to remember a single password, protecting all of you credentials, than trying to remember multiple passwords. Additionally, on ICS, there is no separate password, the credential storage is protected by the device unlock password.

Nikolay Elenkov
  • 52,576
  • 10
  • 84
  • 84
  • I decided to move on with the third option. One problem I am facing now is that keystore associate each entry with application UID. So if install another application with same package name as of former application (of course I have to delete the former application first) and different application signature (Signing certificate) then that application can also view the keystore entries because UID is does not change. – Noor Oct 22 '12 at 12:17
  • Are you sure about this? UIDs do change if you install a different application. – Nikolay Elenkov Oct 22 '12 at 14:09
  • 2
    Actually I am trying to hack my own application. For this I developed another application with same package name and tried to install it on my device (here the signing certificate for this new app is different from actual application). Upon installation of this application android gave my an error that "An existing package by same name with a conflicting signature is already installed". Hence, I deleted previous application and installed the new application. At this point instead of assigning the new application android assigned the same UID which was assigned to previous application. – Noor Oct 22 '12 at 20:31
  • What device and Android version is this happening on? Are you indeed able to access the keys from the 'new' application? – Nikolay Elenkov Oct 23 '12 at 01:19
  • 1) My device is Samsung Galaxy S3 and Android version is 4.0.4. – Noor Oct 23 '12 at 05:43
  • 2) Yes indeed. 3) Do you think that this might be happening because the application is not from android market which I am trying to hack? – Noor Oct 23 '12 at 05:50
  • Not sure what you mean by 'trying to hack', but that probably has nothing to do with it. This could be considered a bug I guess, since there is no way for an app to cleanup keys after it is uninstalled. It would be a bit hard to fool someone into uninstalling a legitimate app, and installing a rogue one afterward for a practical attack. You can try filing a bug at http://b.android.com, but since this is not a public API, I don't know if they will consider it. Try this on the emulator to see if you get the same behaviour. (re-added comment due to too many typos in the original one...) – Nikolay Elenkov Oct 23 '12 at 06:20
  • 3
    I know this is old, but in latest Android master branch, and application's keys are deleted when the application is uninstalled, thus this shouldn't be a problem. With that said, the interface has changed considerably as well, so the code in the blog most probably won't work as is in the next Android version (K-whatever). – Nikolay Elenkov Apr 19 '13 at 06:35
9

Hashing is the solution don't store credentials as plain text in shared preferences or any medium.

Just salt and hash the password then you may proceed to store it in either sharedPreferences or some embedded db.

Here is how it works:

Online

  1. The plain(unhashed) password is sent to server for authentication & authorization upon successful login.

  2. The salt either can be generated and returned from server to client or can be generated at client

  3. Then store it as salt and hash the password and store it.

Offline

  1. We’ll hash the user entered password using the salt which we stored

  2. We'll compare with the hash which we stored upon successful login

  3. If both are equal then we’ll let the user in else we won’t let the user in.

Advantages:

  1. So Now you don't have to worry about version compatibility.

  2. Even If device is rooted it's so hard to brute force the hash.

  3. Even if someone decompiles/cracks the app it's so hard to reverse engineer

Durai Amuthan.H
  • 31,670
  • 10
  • 160
  • 241
  • 2
    The issue with storing via a hash is that hashes are intended to be a one-way street. I believe the user is looking to store the password so they can recall it in order to keep a user from having to log in every time. Encryption is a two-way street, hashes by design are not. – Derek W May 21 '14 at 14:41
  • I think the developer wants to allow users to sign in offline.so As you said hashing is one way street it can't be reverse engineered so its highly secured if hashes match then authentication is success. – Durai Amuthan.H May 22 '14 at 05:17
  • 1
    Yes, for offline authentication that would be ideal. I interpreted financial application as something you would need credentials in order to pass authenticate against a web service to obtain information. It may be beneficial to note the offline aspect in your answer. – Derek W May 22 '14 at 13:16
  • please clarify me on point 3 with hashing. for hashing/encryption you need salt and probably one would have this in source code if someone performs reverse engineering with code then he would easily get that salt too? – RQube Oct 17 '14 at 08:43
  • 1
    @RQube - The salt has to be dynamic the salt generation logic can be server generated so that decompiling the app won't reveal the salt generation logic to the hacker. – Durai Amuthan.H Oct 17 '14 at 09:27
  • 3
    I don't understand the advantage of this. If the server is changed from expecting a password (which it then hashes) to expecting a pre-hashed password then if the hashed password is compromised the hacker can log into the server with it. They never have to worry what the real password was they have what the server considers the "password" to be – Richard Tingle Nov 26 '14 at 23:38
  • @RichardTingle - I have edited my answer to make it clear to understand.Feel free to ask me questions. – Durai Amuthan.H Nov 27 '14 at 08:21
  • Ah I understand, this is about allowing users to log in offline as opposed to creating a persistent log in to the server – Richard Tingle Nov 27 '14 at 09:04
  • @RichardTingle - Yes,Its about securely storing credentials with out any compromise and providing seamless authentication regardless of internet connectivity. – Durai Amuthan.H Nov 27 '14 at 22:18
  • This solution only works if your system can only be accessible via the mobile app. However if you have a web app as well that can use same user log-in data this won't work simply after user change the password via web app and then try to log-in to the app – fernando Mar 27 '15 at 03:58
  • @fernando - If the device is offline and he never used the new password on the mobile then we can't do anything about that he has to use the app when internet connection is available.Let's have a different scenario user has logged in when the mobile has active internet then he suddenly goes to the web app and changes the password then we can possibly use GCM and send a push notification to the device and make him login again or use some other approach like expire all his sessions like that so that he logins again I think this is the best we can do I suppose – Durai Amuthan.H Mar 27 '15 at 08:29
  • How about using the username as the salt? – Toby 1 Kenobi Jul 01 '16 at 05:11
  • How about using the username as the salt? – Toby 1 Kenobi Jul 01 '16 at 05:23
  • @Toby1Kenobi - Just the username would be easy to reverse engineer so you can try using some date time stamp along with username as salt.The date time stamp could not be easy to guess may be u can use user registration date time stamp. – Durai Amuthan.H Jul 01 '16 at 06:12