I'm currently designing an application which has initial login page. I provide remember me functionality and I stored username and password values in shared preferences. I illustrated my sample code below.
SharedPreferences preferences = getApplicationContext().getSharedPreferences("MyAppSettings",Context.MODE_PRIVATE);
SharedPreferences.Editor edit = preferences.edit();
edit.putString("username",username);
edit.putString("password",password);
edit.commit();
Info: Suppose username and password are string variables which are filled by user
Whenever user sets checkbox remember me, I store these variables in shared preferences.
I wonder that is this way safe and reliable for performing this kind of operation?
I mean that can these variables be reachable from outside the application?
Also, do I have to encrypt password of the user and store in shared preferences?
Thanks in advance,
Although Raghav Sood did answer your question correctly, your approach to the app design is fundamentally wrong in my opinion.
Modern day practices dictate that you should not store username and password at all in your app. Instead the login process should generate an oauth token that your app can then encrypt and remember for future access the web-server.
To have a general reading about oauth tokens you can check the wikipedia article on it http://en.wikipedia.org/wiki/OAuth and just as example, twitter uses that approach for apps connected to it https://dev.twitter.com/docs/auth/oauth/faq
I mean that can these variables be reachable from outside the application?
Anyone with a rooted device can view your SharedPreferences. It is simply an XML file stored on the device.
Also, do I have to encrypt password of the user and store in shared preferences?
It would be safer to do so, yes. Also encrypt the username while you're about it.
Make the user submit the username & password
Once the backend validates the user, make the server return a JWT
Store this JWT in shared preferences securely using Hawk
Use this JWT to authenticate user in the future
Related
I'm trying to build a secure remember me system that allow user enter in the app without insert credentials each time.
i found this:
Add a "Remember me" checkbox in whitch was used sharedPreference that seems to me are not te best solution because every rooted phone can easily modify that params.
what's the best practice to follow?
well the idea behind remember me is that you trade in their user name and password for some sort of auth token from your backend, and save that in shared prefs or SQLite. You SHOULD NOT be saving their username and password anywhere. You should be saving a token of some sort for them. if they dont have a token stored keep them at login, and if they do then take them to the main page and send that token to a backend to be validated, and log them out if it is not
You can save credentials in SQLite. Encode them and decode.
You can implement own decoder if you want and saving credentials in SharedPreference.
How can I protect username and password saved in preferences?
Some sample code would be nice.
If you store passwords in plain text in an SQLite database or shared preferences, someone with root access might see them. Encrypting credentials prior to saving them locally would be safer, but still not perfect if someone reverse-engineers your app and gets the encryption key.
Have a look at the AccountManager. Also, this post might help you.
If you find that too complicated for your purpose, at least encrypt passwords before storing them into SharedPreferences! You can find more information, explanation and code here, too.
SharedPreferences sharedPreferences = MyApplication.getContext()
.getSharedPreferences(ApplicationConstants.SHARED_PREF_NAME,
Activity.MODE_PRIVATE);
Shared prefernces are stored under Android/data/data/yourApp on the internal file system of android and it's not accessible to other apps, so you can privately save data on shared preference
ACtually shared prefrence data store in your application memory and no other app can access that so beware of this
If building an application where for sending a series of emails the app must temporarily store the user's password, what is the most secure practice of doing this, if any? If not, what would you recommend?
As long as you are not sending the password over the internet, it should not really matter much. If you do want to be more secure, you could store the password in a string and then after it is no longer needed, overwrite it with a string of identical length.
You could use the shared preferences from the device to store and retrieve the password as a string. This string can be deleted from the preferences once you are finished with it.
I'm writing a web service client and have the three obvious settings: url, username and password. For this the key value pairs in SharedPreferences would be enough. But I hit a roadblock when I wanted to subscribe to more than one server instance. What I need is the three settings stored once for each server instance added by the user. Whats the best approach here? Create a custom settings activity and save it to a file?
You can store a Set<String> in the SharedPreferences. You can use this to store the keys to the other properties.
One way of doing this is to store a set with keys that define each of your servers (for example, "foo.com" and "bar.com"). Then for each server store the properties you need using a known suffix. Lets say you need to the store the username and password for each one, then you would put "foo.com-username" and "foo.com-password" as the keys for the username and password for the "foo.com" server, same with "bar.com".
What is a good practice to save username and password on device?
I have gone through many answers on StackOverflow and now i am bit confused.
I am working on an email app and i want my user to feel absolutely safe while using it.
Some people suggest that we should encrypt it and save it in SharedPreference. Some suggest we shouldn't save it on device at all.
I just want user's details to be stored at safest place possible.
Any help, suggestions would be highly appreciated.
You should save users credentials using the AbstractAccountAuthenticator class. Not only is this super secure, it also makes your app feel more integrated with android. Have you ever gone to the "Accounts" screen in your android setting and seen your Facebook, Twitter, and GMail accounts there? That's because they're using an AccountAuthenticator. Also, it allows you to associate URIs/ContentProviders with particular user accounts. To see a really comprehensive (but complicated) example of all this, checkout the SampleSyncAdapter example.
Do you have any control of the server side, or is this a generic email client? If you can control the server side, I would do something like authenticate, then have the server generate a UUID and keep that locally to future api calls. Another idea would be to send a hash of the password to api calls instead of the actual password, then you can store just the password hash locally.
The issue with encrypting the username/password is that your code needs to be able to decrypt it, and if your code can decrypt it, somebody can reverse engineer your code and do that as well, although you can make it easier/harder by how you code and package it.
Once you figure out WHAT you're storing, you can figure out how you store it. One account? Shared prefs. Multiple accounts? Create a Sqlite DB.
I would suggest using http://ormlite.com/ to handle your db connections. I did a good chunk of the initial Android port work, and its now been enhanced/maintained by a top notch group of hackers. Very solid stuff.
See more Sqlite blog posts:
http://www.touchlab.co/blog/single-sqlite-connection/
http://www.touchlab.co/blog/android-sqlite-locking/
If security is a concern, eventually it still boils down to saving the user credentials in encrypted form. Here are some suggestions:
Consider encrypting the credentials using Base64.
The encryption key should be divided into different parts and saved in different parts of the app. Only to be combined by app logic.
Consider using JNI for encryption part of the code.
Once you have an encryption logic in place, you should use AbstractAccountAuthenticator.
Remember two things:
a. An apk can be decompiled to retrieve the key. (Thats why (2) and (3)).
b. Saving plain text is disastrous. (Thats why (1)).
On second thoughts, once you have 1, 2 and 3 in place, you may use SharedPreferences as well.
SharedPreference is the best option.
Ease of Use
Only deleted when user clears data for the App
Flexibility to change values when user uses another set of login credentials.
Here is how you can do it.
import android.preference.PreferenceManager;
private static final String LOGIN_EMAIL = "login_email";
private static SharedPreferences mAppPreferences;
private static SharedPreferences.Editor mEditor;
/*Insert your code to Get user entry of email from the EditText*/
mAppPreferences = PreferenceManager.getDefaultSharedPreferences(context);
mEditor = mAppPreferences.edit();
mEditor.putString(LOGIN_EMAIL, v_user_email );
mEditor.commit();
I don't think SharedPreference storage is unsafe or can be tampered with.