Secure preferences or database file in the data directory - android

I have been creating an app in Android recently, which has a login page. It's fully offline, so online or network-based solutions would not help me. I think there are two approach for me to accomplish this task.
Saving password hash in the preferences XML file
Saving password hash in the SQLite database
However, in my opinion both of these ways could be insecure because an user could load my app's data directory in a DDMS and then take out my preferences or database file and subsequently try to manipulate it.
Now, my question is:
Is there any fully secure approach (preferably not using files) or way to encrypt preference or database file?
Thanks in advance
SOLUTION (idea from Marcin Orlowski)
A relatively secure solution would be hashing password along with another string, which is only known to my app (with assumption of no resereve engineering), with this conditions, the attack could not replace my hashed string with his own hashed string.

No, there's no bullet proof solution. What's in the app can be extracted with more or less efforts or your app can be hacked/etc. If you need to store password, do not store plain as plain text. Do sha1 or md5 hash of it first and store the hash, so even if one would get hands on your prefs/DB then he still does not know the password (but he can try to brute force it using i.e. rainbow tables etc). Depending on sensivity of data you protect with password, using hash may be sufficient (if you do not encrypt data itself, then it makes no sense to go further)

Save the password hash in the private ContentProvider. SharedPreferences XML and Database file can only be get from DDMS if user uses rooted phone.

Related

How to keep passwords securely in android using shared preferences or sqlite database?

I am building an app which generates a random password and you can keep it along with your other details such as username, website url, name etc.
Basically a password management thing.
Things to be stored:
When I am clicking on the save button, I wanted it to be saved somewhere locally. So that, I could retrieve them and display it in another activity.
Can I share those things in SharedPreferences for all those password entries securely? [By password entry, I meant the entire class ]
I have referred to something like ComplexPreferences [ http://blog.nkdroidsolutions.com/class-object-in-sharedpreferences/ ]
I've tried them because I had created a class containing all these data [title, url, username, password, notes]. But I cannot retrieve them properly using a recyclerview. I'm ending up with some error.
If it cannot be done with SharedPreferences, how can I do it with SQLite Database?
But how can I save them securely? I don't know much about security in Android.
Please guide.
The shared preferences and sqlite db both are secure for an extend only.
It can be easily accessanle and can be modified even there are several apps available to edit the shared preferences and sqlite db in playstore . **
So i prefer not to store it locally
.you can use some kind of **algorithms and mechanisms to encrypt and decrypt the data that you are going to store locally.
if the device is rooted then its a SERIOUS ISSUE
Let's say, that you have a generated password along with other details like user name. Storing this kind of data is a perfect fit for SQLite. But, storing in plain text is not safe. Either the whole database or individual records should be encrypted. The former can be done using one of the open source database encryption libraries. For the later you have a couple of options:
Ask the user for a password each time he opens the app. Generate the actual encryption key using password-based encryption and the same salt value.
You can use the Android Keystore Provider to generate an encryption key and save it for you in a safe location on the device. Later, you retrieve the entry from the keystore and use it to encrypt/decrypt your database records using javax.crypto.Cipher.
Both options ensure that the encryption key is not be present in the app.
I still don't understand, why you need to save it locally? If only your application will be able to unlock data. In this case, only your application will have keys to working with this files.
For this example, you can easily work with SharedPreference with Private Mode. Furthermore, it's enough for most tasks. We using this option to save User's token, and it's Ok, for system. (If we talk about safety of this way, so you will have some risk for custom ROM, for Users, which manually flashed on device.)
If you need more complicated things, you can use sample, for using Android Keystore, with generating Key Pair, and saving data. For example you can check this source.
UPDATE!
So question was updated a lot, from first version. I will update information what you a looking for. Saving huge encrypted information locally.
Maybe easer way to do it, it's just use local encryption of data, as I described above, using Android KeyStore, KeyChain (links above). You will create our own KeyPair and will use for encryption and descryption some data. But this data, you will save in your DB in encrypted view.
Another more complex solution, will be creation of mechansim for encyption/decryption DB. As you described, you will save all information in DB, and after, just encrypt/decrypt you DB files. Fortunatly, we already have such library SQLCipher, just take a look. Fore example, this is pretty simple tutorial

How to store the key used in SQLCipher for android

I am using SQLCipher for Android. I have done all the necessary things that are needed for
loading the libs as mentioned in http://sqlcipher.net/sqlcipher-for-android/
I observed that you set the password i.e the key in :
SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(databaseFile, "test123", null);
Then how is your password safe from a hacker? As it can be accessed from a java file. ?
Is there any correct way where i can store the password ?
Thanks,
Nibs
Then how is your password safe from a hacker?
It's not. Hard-coding a passphrase makes for simple demonstrations, though.
Is there any correct way where i can store the password ?
The user should supply the passphrase for the user's database via your UI. The user then stores the passphrase in the user's head, or perhaps you combine what's in the user's head with something else for lightweight two-factor authentication (e.g., MAC address of paired Bluetooth wearable).
I would like to suggest the following approach:
The first time you create the database you have to create a random password.
You store this password in the Keystore.
Whenever you open the app you read the password from the keystore and use it for connecting to the database.
So how does the keystore access work? See blog entry 1 and blog entry 2 and the corresponding github repository. The solution is available for Android version 2.1 to 4.3.
Big caveats:
The solution works only with private API access, so it might break in the future.
A screen lock password is required to store keys and all keys are wiped if a user removes his lock screen password.
What is being overlooked is the fact that the demonstration given by SQLCipher is purely for demonstration . It is up to the imagination of the developer to overcome the obvious. Slightly less obvious is that you would NOT store the key in a private local variable, since performing a strings search against your class files could reveal your key, reducing the dictionary necessary in a successful brute force attack. Open your classes.dex in a hex editor and try it.
It isn't the .java files you should be concerned with, as only your developers should be in there. It's the .class files. The next level of effort is some effort of obfuscation, but that really only limits the impatient.
Take a look at this discussion
https://groups.google.com/forum/#!topic/sqlcipher/OkE0rUwXEb8

Storing password for an offline app

I'm developing an app where the user can use it in remote locations. I've created a startup dialog asking for password. I saved the password in SharedPreferences.
My question is, is it a good idea to do that? Or is there a better way for storing passwords for offline apps?
Because when I try to clear the data of my app in settings -> apps, my saved password in SharedPreferencesis also being deleted.
you can hash your password and store it in a file
search for hash function like MD5 or ..
Basically clear data of your app is cleaning what you store in SharedPreferences so that is normal. Store data in with SharedPreferences is usefull but someone with a rooted devices can access to these datas (basically an xml file store in "/data/data/app_packages").
Then you seriously have to consider to encrypt your password before to store it with SharedPreferences.
My question is, is it a good idea to do that?
Generally, it is not a good idea to store passwords in plaintext,
even if it is an offline application and gets cleared sometimes anyway.
Like you mentioned before, all that Information and even the database can be extracted from your Applicatoin Storage when the device is rooted.
Even If the content of that application is trivial, someone can do what mentioned above, just to see what password you use, so he/she can try to hack other accounts of yours..
This is especially the case if more people are using this application.
If you are aware of, and OK with that, you surely can use SP or DB.
If you want to do something in the right direction, you can encrypt passwords,
or hash them (though I recommend not to use MD5, but something like SHA2,Whirlpool,RipeMD2 or even PBKDF2).
Using an encrypted Database like SQLCipher is also nice, since you have to set it up only once, and everything that is added in to your application
afterwards is automatically stored encrypted.
If your only concern is that you dont want to the passwords be deleted, well, if you don't have Server communication, you have to live with that risk :)

Where to store my keys to encrypt data on mobile?

I don't understand what the hacker can see and cannot see when he enters in a mobile app, for example android. He decompiles the .apk, then sees some .class files. If for example, I encrypt a key/value pair in a file, I still need to call this key from the code, and if the hacker can see the code, no matter if the key is encrypted, he will know which key I am calling?
My goal is to keep some encrypted string in my app, for example the twitter account Id of my app.
Some topics talk about " a private key to read, what was encrypted with a public key ", but if I use them, I still need to store them somewhere in my app...
Don't completely understand your requirement but the rule-of-thumb is always assume that client is not to be trusted.
You have to ensure that
All decryption should be done in your server (which you trust).
The client should never be able to access the decrypted data (unless you want it to). Hence whatever part of your code that needs to directly access the decrypted data should be in the server.
The client should have only the encrypted data (if it must store data).
The client should not be able to access the private key you used to encrypt the data.
If in your case your client must be able to access the critical data directly, then your only resort is to use obfuscation techniques (Basically hiding your data/code, to make it hard to find/understand). Of course all obfuscation techniques can be defeated eventually by a determined hacker. You have to decide how valuable your data is, what are the probabilities a hacker will try and access your data.
To take an extreme example : storing your twitter account and password using obfusucation is very bad. Storing a twitter-url- might not be so bad.
you can get your keys from server while launching app. and also dont manage in app purchase detail in sharedPrefrence or Sqlite. because in rooted device user can see that data file from root browser or sqlite editor application so user be able to change value.
A very determined person can crack it, but it's a major pain to crack encrypted strings and will stop most hackers. Especially if you obfuscate your code with something like ProGuard.
Answer to a similar question for details on how to encrypt

Encrypting strings

I have an Android application and within it some strings which I send through htpps. Is it possible to encrypt those hardcoded strings (such as for example passwords) in Android application to be unreadable from the apk file?
Regards,
So if I understand your question correctly, you want to store encrypted strings within the Android apk file (in strings.xml for example). If this is the case, yes, you can absolutely store encrypted strings wherever you please.
The kicker is that in order to decrypt these strings, you'll need a key. Wherever you end up storing the key becomes the weak link in this chain. If your app is reverse engineered and someone gets a hold of the key, your strings are no longer encrypted.
So to answer your question, no, it's not possible to do what want.
Check out What is the most appropriate way to store user settings in Android application and a whole bunch of other question. Basically you can obfuscate and encrypt to some extend but you will never be completely safe on a rooted device and against network sniffing attacks. That said though that applies everywhere.. find your best compromise between level of effort to implement and crack and the data you are protecting.
I think you should explain what do you want to do with this strings.
If you want just send password to server and make some kind of authorization, you can use MD5 or some other hash function to hide thode values. Hashed password can be compared with hashed password at the server side.
If you want to send encrypted text and decrypt it at the receiver side then you have to use some encryption algorithm, e.g. DES (some kind of encrypting key will be needed).

Categories

Resources