I'm trying understand which is the best way to store sensitive data in Android. In my app i want to insert a classic in-app-purchase model with some coins. My problem is that i'm not sure how to implement this correctly.
The initial idea was to simply use my firebase database, store the number of coins for every user and fetch the data every time the app is launched. This way I can easily detect some inappropriate usage but my users are forced to use the internet to play.
Looking at the documentations, I found this. Can this be a solution? Can I save in the internal storage the number of coins, maybe with some type of encryption, to avoid root user to modify the file? Then when the internet is on I can double-check the local stored variable with the the one in the database.
Thanks
Not an "easy" task.
Technically, you can create a SecretKey and encrypt data, so no normal user will be able to reproduce. If your concern are root users, You are kind of out of luck, as he can hook into your app while it is reading/writing that value.
But to store it online is not a solution in itself. You have to answer questions like: "Do you trust any server input"?
"How to make sure just paid coins are added"?
Have you had a look at Google Play billing?
it provides safe way's to determine if somebody paid or not.
This will require to be online.
If you have a sensitive data to save you can use sqlcipher database .. the good with it that it encrypt the database file itself so even the root user be able to get the database file he will not be able to decrypt it if you use a secured encryption algorithm.
you can find more about sqlcipher here
https://www.zetetic.net/sqlcipher/sqlcipher-for-android/
Since I assume you will grant your app a reading permission of your sensitive data and all writing processes should be reserved server-side, I would not recommend storing the data in a file on a phone, though every encryption can potentially be passed.
Maybe you already have heard about SharedPreferences, which is a good solution for let's say Preferences the user selects and that only shall affect his particular installation of your app. The difference is, that values are not stored in an external file, so not that easy accessible, BUT your app needs to write them, due only the app can access them directly (also your server can't). I am not aware of how your sensitive data is used at all but I would also not use SharedPreferences since it's injective-prone.
Official docs about SharedPreferences.
If security of your data (speaking of Confidentiality, Integrity, Authentication) is your No. 1 priority, simply don't store your sensitive data on the users device. Focus more on creating an API that ensures secure and performant passing of the relevant bits of your sensitive data. Hope this helps to give you a view of which way to go and which to walk around.
Related
I have an integer variable in my application which I want to save for future use. Depending on it's value (like when the value is 0), I will be blocking a functionality of my app and will be requesting an in app purchase for the same.
If I save it anywhere in internal storage, it'll be flushed after Clearing Data, and if I save it in external storage, the path of the file can be easily found by decompiling the code, and server based solutions are out of my scope.
I know that a full proof security is almost impossible, and you might be thinking of downvoting my question, but I really need some advise from experts like you so that I can at least achieve maximum security, so that I can somehow figure out that the variable's value has been tampered and in that case I'll reset it to zero.
I think there is no way to secure the variable without the server implementation, so in order to achieve your functionality you can perform following steps.
First you need to check the In App Purchase product status - If it's purchased by user then you need to unlock the next functionality.
If user has not purchased or subscribe using in app purchase then you need to lock the next functionality.
In case if you want to protect stored data from reading you can use encryption to store something in the file and then use it in your application. Yes, somebody can find a path to your data, but it would be hard to read it. Also it's impossible to modify data, only corrupt.
On the other hand, it's better to use internal storage or preferences. And yes, data actually should be cleared by clearing application data. You should create default value at the start of your application, if requeired field is missing, and store it. Nothing should remains on device if user delete application\clears data.
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).
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
Is is possible to restrict user, from accessing any application data, like SQLite db file, shared pref. file..etc. I have restricted it to certain level. But still, user can access these file, if he boots the device as root user, or super user.
What needs to be done, to restrict the user from accessing my secure application data?
I saw a blog on this somewhere (I'll get the link if I can find it), but basically, there's nothing you can do. The blog author says that whatever data you put on a user's device is now theirs, and if they want at it bad enough, they're going to get it. A root user has access to everything on the device. That's what rooting is supposed to do.
The only way to really protect your data is to pull it from a secured server and not cache it, which is the only way you should be doing it, if you want to keep something from your user.
Found the blog post, suitably titled, "It's the User's Data, Dammit."
http://commonsware.com/blog/2012/05/01/its-the-users-data-dammit.html
You should really subscribe to this guy's blog. He's got some good stuff on there. (No, I'm not plugging. I wish I could be this guy.)
If the phone is rooted there is little you can do to stop access to files stored on the device.
The best you can do is encrypt the data written to the file or the fields in the database using a key that the user has to enter every time they start the app.
I'm developing an application which will be storing user sensitive data. My issue is using other applications that a user can view that stored data with. Then I need to provide better security for the data in general.
Is there any way to provide better security for SQLite database and tables?
Encrypt your data before you enter it in the database. As far as I know, the SQLite database is kept in a single file somewhere in the /data/ directory. What is more, your data is kept in plain text format. This means that it will always be possible for someone to extract that data by rooting the phone, obtaining the .db SQLite file and opening it with a text editor.
So, encrypt your data :)
--
Okay, maybe not a text editor, but a simple hex editor. Anyways...
Check out SQLCipher for Android. It's free (Apache 2 and BSD licences).
PS.: Some ORMs also support SQLCipher now, e.g. our greenDAO.
The author of sqlite offers a version that encrypts data. It's not free though
You could encrypt the data using a user specific salt retrieved from your server. That way, even with root access you would need the users salt to decrypt the database. Since you have control over the salt you provide an extra layer of security, however, your user will always need a network connection to access their data.
why are you keeping sensitive data on the phone? If its sensitive, why not send it back to the server where you have control over things. If the user roots their phone, they can basically do what they want. Other than that, encrypting like Shade mentioned would probably be your only option...
Good way to protect the the Database is to use the password Protected database and you can create it by using
1- android Sql3 wrapper library
2- libsqlite3_jni.so
also please read the article below are make your search on the option above, i hope this would help much.
http://www.findbestopensource.com/product/sqlite3-android