Android: Storing Username and Password

Android: Storing username and password?

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.

Saving user credentials

Problem

Storing the plain username/password in mobile apps is not recommended, because it's not secure.

Solution

Using Token-Based Authentication, its workflow like this:

  • Client sends username/password to the server

  • Server check the username/password is valid, then generate a token and send the token to the client

  • Client saves this token to local storage, such as File, SharePreference, Database etc.. and use this token to call APIs from now on

Benefit

  • Don't need to store the plain username/password

  • You can store the plain username if users log out and exit the app. Next time they open the app, we could display the username on the Login screen (better user experience), they just need to enter their password.

Token usually has time expired, it means how long does it live. When a token is expired, you have 2 solutions:

  • Log out of the app and display the Login screen, users need to enter their password to get a new token

  • Using refresh token to get a new token

Back to your concern

The user has the choice of staying logged in the next time the application is turned on. If he chooses not, I still have to keep the user credentials until the application closes (due to API queries while the application is running).

  • When users choose "Do not stay next login" option, you should save it into local storage

  • Each time users open the app, if this option is true, then clear token, display the Login screen.

  • If this option is false and the token is not expired, go to the Home screen, otherwise get a new token.

Update

If you cannot change the authentication mechanism of the system, then you should you one of following options:

  • EncryptedFile

  • EncryptedSharedPreferences

See more information here.

Android - Where should we save username and password in device memory?

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.

android Store User name and password in database and use it for multiple activities

You are storing "logged in" key which is helping you check user is logged in or not. And it is persisted in the application.

You can do the same thing to store username and password by storing HashMap in sharedPref.

Map<String, String> map = new HashMap<String, String>();

map.put("username", username);
map.put("password", password);

SharedPreferences prefs = context.getSharedPreferences("TEST", 0);
SharedPreferences.Editor editor = prefs.edit();

for (String key : map.keySet()) {
editor.putString(key, map.get(key));
}

editor.apply();

Get value from sharedPref

 SharedPreferences prefs = context.getSharedPreferences("TEST", 0);
HashMap<String, String> map= (HashMap<String, String>) prefs.getAll(); //Get all list of saved username and password

for (String key : map.keySet()) {
String value=map.get(key);
}

Your activity :

public class Login extends Activity {
public static final String PREFS_NAME = "LoginPrefs";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);

HashMap<String, String> map= (HashMap<String, String>) settings.getAll();

if(map != null && ( map.containsKey("username") && map.containsKey("password")
map.get("username") != null && map.get("password") != null){

Intent intent = new Intent(Login.this, MainActivity.class);
startActivity(intent);
}

/*if (settings.getString("logged", "").toString().equals("logged")) {
Intent intent = new Intent(Login.this, MainActivity.class);
startActivity(intent);
}*/

Button b = (Button) findViewById(R.id.loginbutton);
b.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
EditText username = (EditText) findViewById(R.id.login);
EditText passsword= (EditText) findViewById(R.id.password);
Snipper usertype= (Snipper) findViewById(R.id.ut);
Snipper ctype= (Snipper) findViewById(R.id.ct);

if(username.getText().toString().length() > 0 && password.getText().toString().length() > 0 && usertype.getSelectedItem().toString().length()>0 && ctype.getSelectedItem().toString().length()>0) {
//if(username.getText().toString().equals("admin") && password.getText().toString().equals("admin")) {

/*SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("logged", "logged");
editor.commit();*/

String uname = username.getText().toString();
String pass = password.getText().toString();

Map<String, String> map = new HashMap<String, String>();

map.put("username", uname);
map.put("password", pass);

SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = prefs.edit();

for (String key : map.keySet()) {
editor.putString(key, map.get(key));
}

editor.apply();

Intent intent = new Intent(Login.this, MainActivity.class);
startActivity(intent);
//}
}
}
});
}

Please read SharedPreference tutorial.In this activity how i mention the SharedPreference get use same way you can call it using LoginPrefs key.

Hope it will work for you.

Cheers...!!!

Best place for storing user login credentials in Android

You should NOT use SharedPreferences, despite how secure Google will tell you they are, for the simple fact that rooting habits are widespread by both power and wannabe-power users.

In rooted systems, authorized apps will be able to access the internal storage /system partition, thus access the root-owned encrypted XML files where Android stores SharedPreferences, WHICH BECOME CLEARTEXT FOR ROOT-AUTHORIZED APPS. So if a compromised phone happens to have an app that stores such data and the user has a habit of abusing same email/password for different services, the attack vector is pretty straightforward to compromise credentials for multiple services, despite whatever warnings the user dismissed when rooting his phone or giving the app such permissions, because, well, those warnings just aren't clear enough.

Alternatives are manual encryption of persistent storage for credentials, using custom, variable seed, salted algorithms. secure-preferences lib is a great alternative which pretty much does everything for you in a transparent way, with the added benefit of implementing Android's SharedPreferences interface, keeping most functionality of default sprefs with minor tweaking (look at their samples).

2016 Edit: I just felt I needed to come back to this question in 2016 and add a nice reference to the Apple vs FBI drama to alter the OS in the San Bernardino assailant's phone. So, imagine you have a phone that is easily rootable, like most Android's, and that might even be rooted by default or doesn't need to wipe data to root. The FBI doesn't have to demand anything from Google or your company if they wan't to get your credentials. By using stuff like secure-preferences, you place the same type of responsibility Apple decided to undertake by only making your own system (in this case, your app) able to access those credentials. You do get to be annoyed by the FBI if they so desire, but giving your users the sense that you, not the underlying OS, is the only authority having direct control over those credentials, is something I'd rather have in my product.

Android. How to save user name and password after the app is closed?

Try this way: defined Preferences first

private static final String PREFS_NAME = "preferences";
private static final String PREF_UNAME = "Username";
private static final String PREF_PASSWORD = "Password";

private final String DefaultUnameValue = "";
private String UnameValue;

private final String DefaultPasswordValue = "";
private String PasswordValue;

And onPause()

@Override
public void onPause() {
super.onPause();
savePreferences();

}

And onResume()

@Override
public void onResume() {
super.onResume();
loadPreferences();
}

And here savePreferences()

private void savePreferences() {
SharedPreferences settings = getSharedPreferences(PREFS_NAME,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();

// Edit and commit
UnameValue = edt_username.getText();
PasswordValue = edt_password.getText();
System.out.println("onPause save name: " + UnameValue);
System.out.println("onPause save password: " + PasswordValue);
editor.putString(PREF_UNAME, UnameValue);
editor.putString(PREF_PASSWORD, PasswordValue);
editor.commit();
}

And here loadPreferences()

private void loadPreferences() {

SharedPreferences settings = getSharedPreferences(PREFS_NAME,
Context.MODE_PRIVATE);

// Get value
UnameValue = settings.getString(PREF_UNAME, DefaultUnameValue);
PasswordValue = settings.getString(PREF_PASSWORD, DefaultPasswordValue);
edt_username.setText(UnameValue);
edt_password.setText(PasswordValue);
System.out.println("onResume load name: " + UnameValue);
System.out.println("onResume load password: " + PasswordValue);
}

Storing username and password in plain text

Answer mentioned by Greg Ennis, provides you the code to encrypt the string. We have various encryption algorithms for this.

Now the challenge is - what if the application source code is reverse engineered and the data is stolen ?

To protect the code against this, try the below solutions.

Solution 1 - Proguard

ProGuard obfuscates the Java jar file before it’s converted to a classes.dex file.

Refer to the SO Link Enabling ProGuard in Eclipse for Android to understand how to configure proguard in your application.

Read this link to understand the different options we can configure in a proguard properties file. http://proguard.sourceforge.net/manual/examples.html#androidapplication

One other easy option would be to use the proguard GUI

To launch the GUI, download it from SourceForge at
http://proguard.sourceforge.net. Unzip it and execute the following command
in the lib folder, assuming you’ve copied your target proguard.cfg file into the
proguard\lib folder. You should see that many of the optimization options

Solution 2 - DashO interface (Commercial Tool)

This includes Control Flow,Renaming, and String Encryption obfuscation options.

  • Control Flow - Reorders the bytecode and aims to make it impossible
    to decompile.
  • String Encryption - Encrypts many of the strings, which
    can be very useful as another defense against someone stealing API keys or
    passwords.
  • Overload Induction - Class renaming: more than one class can be named a() or b() because
    doing so is legal Java, as long as the classes have different method parameters.

Using a DashO interface is very simple with the GUI.

Hope this information helps.

How to store username and password details from my app to my database and how to connect my app with my database?

You can refer to the sqlite database tutorials to store the data into the database. If you are storing the data in the database that is in the server, then also see the tutorials on connecting to the server database using any volley or retrofit etc.

Always its better dont store password in the text format, hash it with the hashing algorithm like SHA256, MD5 etc and then store it.

In the sqlite tutorial you will get the method to retreive the data back from the database and from there once the login button is clicked match the hashes of the data and allow to login.

https://www.tutorialspoint.com/android/android_sqlite_database.htm



Related Topics



Leave a reply



Submit