I have a dilemma, i need save some security data on my Android device, this data is login information to personal cabinet, so can you please, give me an advice where is better to save this info into simple txt file(but what about security?) or maybe is there analog of MySQL DB in Android platform(and how i can access it)?
The best way to store personal data in Android application is using shared preferences with mode private, so that nobody can access that data other than your application.
for more details see Android developers tips about shared preferences here.
AFAIK you cannot run MySQL on a android device but you can use SQLite (tutorial). You could even try using SQLCipher to store it in a encrypted database. Although I'm told it's not too hard to extract the access key from your APK.
When you store you password, make sure you encrypt it (even if you are encrypting the database). Storing passwords as plain text is rarely a good idea ;)
Whatever you do, do NOT store it in a text file!
You can save the simple txt file into your application directory. In General, Android assigns each application a unique uid. Each application has its own application directory with mode 660. So other application cannot access its content. To write your own application directory, you can use the following code:
String filename = "myfile";
String string = "Your security content";
FileOutputStream outputStream;
try {
outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
string = encrypt(string);
outputStream.write(string.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
However, if the target device is a rooted device, other application can access your file. So a better approach is to encrypt your data, and save it into the application directory.
For a database approach, it has the same problem, you can define your own content provider without exporting it out, but it is still vulnerable on a rooted device. So whatever you choose, writing txt file or storing it on DB, encrypt it first is necessary.
You could store the details in the SQLdb on android but save all the form details using encryption and just persist the strings.
You can see in the answer below an example of someone doing this exact same technique and using the phoneId for the encryption (although I'm not sure how safe that really is).
Is it safe to store username + passwords in a local SQLite db in Android?
Related
I have a problem. I am using xyz.db file and which is stored in asset folder. I am copying all data from xyz.db to application db which is stored in data/data/com.xyz/abc.sqlite in storage folder. Now I want to secure asset's xyz.db file. Because It can be easily extract from apk by reverse engineering. Please help me to secure my asset folder's database file.
You can perform the following to make it relatively difficult to access data in DB.
Password protected zip file to contain db which at runtime should be extracted.
Encrypt the file with symmetric key and again at runtime decrypt it.
Utilize sqlcipher that performs encryption for Data at Rest.
In both the above cases you will need to worry about storing the password or key. There is no sure shot way to protect the file but the above would require more effort and should be added as basic protection.
There's no final solution to your problem.
Any technique you'll use can be beaten by a determined skilled attacker.
You have to accept that if you want to store database xyz.sql in your apk file and you later want your app to use it, then it will be also possible for someone that reverse your app to retrieve it. Basically just because the plain text information at a certain moment will be available on the phone.
Hope i've been clean enough
Keep security in mind
As usual in Android the access rights of the database file determine who can use your database. If you follow the standard way presented in the following posts of this series, your database file will be located within the private directory of your app. This means that your app owns the database file and no one else can access it. Even using the other less common ways to create the database you can only grant access to the file. Thus others can access all of your database or nothing. There is no middle ground.
Still: You should never rely on data being safe from prying eyes in the database. Any sensitive data should be encrypted. Very sensitive data should not be stored on the device at all. Keep in mind that if the device gets lost, any misbehaving finder of the device can gain access to the database file as well as to your app. On a rooted device all files can be read. Apps like SQLite Editor make it easy to read even sensitive data – if they are not encrypted:
In cases where data privacy is of utmost importance, you have to revert to secured services or force the user to enter a secret every time before encrypting and storing the data or reading and decrypting them respectively.
source
As I understand it, it's possible to retrieve data stored in SharedPreferences. Therefore it isn't safe. Could anybody advice me on a way to completely secure the data? I know it's possible to encrypt and store the data, but I'm wondering, is there any other way?
Data stored in SharedPreferences, if created with Context.MODE_PRIVATE, is only accessible to your own application.
Though, if the users phone is rooted, then the data can be read by root applications (even if created with Context.MODE_PRIVATE).
There is no way to avoid that, ever. But you can take precautions such as encrypting the data in SharedPreferences.
A good example of this is the SecurePreferences library: https://github.com/scottyab/secure-preferences
Shared Preferences are stored as a file in the filesystem on the device. They are, by default, stored within the app's data directory with filesystem premissions set that only allow the UID that the specific application runs with to access them.
So, they are private in so much as Linux file permissions restrict access to them, the same as on any Linux/Unix system.
Anyone with root level access to the device will be able to see them, as root has access to everything on the filesystem.
If you're concerned about such access to your preferences (or any data written by your application), then you will want to encrypt it. You can google it out.
Try this https://prashantsolanki3.github.io/Secure-Pref-Manager/ to easy work with shared preferences, it also encrypts the key and value before saving it in the preferences.
Sample code to save a value:
SecurePrefManager.with(this)
.set("user_name")
.value("LoremIpsum")
.go();
I need to save some int and boolean for the setting, and for now i'm doing it with SharedPreference, I'd like to know if there are problems with this way, can i stay sure that those data won't be touched or lost? There are contraindications in using this way?
And now the real problem: i need to save some strings, that are basically something like... text description of some urls and the urls, but i don't really think that SharedPreference would work since i don't know how many those items can be, they may be 5, 8, 10, i don't know, those data will be downloaded via internet, so: how could i save them?
I'm not really good at Android programming, but i studied Java a lot of time ago, could i just save it as a file and parse it? I think I could create a Serializable wrapper class and write the items in a file but... is it really safe? users could edit those file or delete them, i think it maybe better if i could save them in some... "locked for app-only" folder, does something like that even exists? And if yes, how do i access it?
I highly recommend using Facebook Conceal. SharedPreferences can be modified by root user independently on used MODE, Conceal keychain file can not.
Conceal creates encrypted file that can be accessed only by the app and your settings are safe. Of course user can delete this file, but you cannot prevent deleting data, only modifying.
Very easy to use:
// Creates a new Crypto object with default implementations of
// a key chain as well as native library.
Crypto crypto = new Crypto(
new SharedPrefsBackedKeyChain(context),
new SystemNativeCryptoLibrary());
FileOutputStream fileStream = new FileOutputStream(file);
// Creates an output stream which encrypts the data as
// it is written to it and writes it out to the file.
OutputStream outputStream = crypto.getCipherOutputStream(
fileStream,
entity);
// Write plaintext to it.
outputStream.write(plainText);
outputStream.close();
Enjoy ;)
SharedPreference is based on a xml file stored in app folder. It's secure like write info on another xml file. It's mainly used for app configuration. For other kind of data, it's better to use database (SQLite) or in json (more performance than xml).
In android, you will use many concept you already studied on desktop version of Java. But the platform is quite differente, especially on performance point of view.
sharedPreferences is completely safe to use, plus the privacy you declare the class to instantiate, can be used only by your application and can also give permission for use by other applications giving property Context.MODE_PRIVATE. The only way anyone can see your settings is to be a root user and also that the user knows the route to follow to find the .XML on your preference, personally SharedPreferences is entirely feasible. Another way would be to use a SQLite database, but as a root user preferences can access your .DB and modify any database manager data such as navicat
In Android apps are like users in Linux system, each user has its own private space, the same goes for apps, each application has its own storage space, and that's where data related to an app will be.
By default SharedPreferences are stored in MODE_PRIVATE, so they will be accessed only by your app, no other external app would be able to access them. If you want to share some of your preferences you can choose other storage modes MODE_APPEND, MODE_WORLD_READABLE, and MODE_WORLD_WRITEABLE.
All that has been said about the MODE_PRIVATE is applicable in the case of a not Rooted device.
For more details on Android Security you can check these resources
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.
I'm building an Android game and I'm not sure where I should save something like "last completed level" or "remaining lives".
I'm pretty sure that I should not save this information in the database, because it's really simple to access an app's database with root access and some SQLite browser.
And I don't want to send it to a webserver, because the game should be playable offline.
What is the most secure place where I can store this information to prevent the player from cheating?
Thanks in advance
You may wanna try one of the three options described here :
http://developer.android.com/training/articles/security-tips.html
Since android is base on UID, it is almost impossible to prevent root user to retrieve data, but you can still encrypt it .
I would go for the internal storage with encryption, and skip the content provider option due to the few data you will store
You could use a non secure storage (like SharedPreferences for example) but use a digital signature to make sure that the value wasn't tampered with.
So you can use Cipher to save your game information file
check this https://stackoverflow.com/a/10782267/2773264
or you can save your file as Object by using ObjectOutputStream
(don't save String Object, save a custom class to prevent from cheating).