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.
Related
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.
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).
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.
We're working on a fairly enterprise-y app right now, and the mandate has been that all data be encrypted on the local disk. Currently, the way to do this is to use the username/password entered on login to build the encryption key. Those values are always kept in memory, so it would be reasonably difficult for somebody to hack that (not impossible, but difficult).
Now the app needs to use SSO to log in. Depending on the provider, the implementations will differ, but lets say we can imagine some unique value being generated either by our server, or using the values available from the AccountManager, or something more exotic. However its done, we need a way to build the encryption key from source values that aren't kept on disk. As mentioned above, those are currently username/password, and for SSO, would be presumably something generated in another fashion.
If we were always online, we could rely on the server to keep that value in a database and return it on login. However, this app should also be able to function offline (after you've done your initial login, of course).
Any thoughts? I had explored just encrypting the whole disk, but we can't really enforce users doing that, and if there's a good chunk of data already, it'll take a long time.
Is there a way to keep these values somewhere in the OS that's not easily readable, even with root? For example, if we had a lock screen, is there some way to use the lock screen password to hold encrypted data? Its my understanding that that's the method used for the disk encryption, and there's something similar on iOS. I've read in a number of places that a 4 digit code isn't not incredibly secure, but it would be pretty good, and much better than what we have now.
Any other thoughts? I feel like I'm missing something obvious.
Thanks in advance.
I'm wanting to create an android app that gathers information and then uploads to a server -- however I don't want people to be able to edit the file before it's sent to the server. I can do the first part of it, but am unable to do the second part. Can anyone tell me the best way to go about this? I don't mind if the user knows what's in the file, just don't want them editing it and then uploading their edited information to the server.
You're pretty much out of luck since the application is run by the user and the output is controlled by the user. The only way you could take over user's system so he would have no control over it would be using trusted computing with all of the ethical and philosophical implications - see eg. Can You Trust Your Computer? by Richard Stallman. The only thing you can hope for is having a secure connection between your server and user's systems (SSL/TLS) but this is still user's system over which you have no control.
The only correct answer here is Zed's.
The rest of the answers rely on Security through obscurity.
The bottom line is: if device is not totally locked down (= trusted computing) then users can reverse-engineer the application/file-format/network-protocol and submit false data.
Fact of life: people with huge resources (media industry, IT industry) have tried to pull this off (DVD, BluRay, game consoles, etc..) but eventually talented engineers on minimum budget have been able to break this protection schemes.
So, it might work, but only if data is not important and nobody bothers to break it.
There are a couple of approaches you could use here:
Encrypt the file before its saved to the device, the user will be unable to read/modify it.
Encrypt the connection to the server, SSL can protect against a 3rd party interfering with it.
Don't save the file in a public location, place it inside your app's private data directory. The user will be unable to access it.
Depending on how sensitive this information is going to determine which combination of methods to use.
Well as for Android you cannot prevent people from accessing files on the public filesystem.
Maybe there are better ways to handle this but I would simply crypt and decrypt the data before submitting and by using a passphrase or some sort of parity check one could validate the data.
Some rough ideas:
You could view the information that is being sent to the server to the user and then ZIP the file that's being sent with a password beforehand so the user doesn't get a chance to edit it:
Write a password protected Zip file in Java
Of course, you'll have to make sure the user doesn't know the password ...
Or you could build a checksum of the text that's sent and validate the checksum on the server. Here, again, you have to make sure the user doesn't know how the checksum is built and change it accordingly.
Or you could not safe the information to a file at all but into the app's database or private filespace (where non-root-users can't access it).
Whether it's the pasword or the checksum, you could send that information to your server with a normal HTTP-request so it won't be "visible" to the user (followed by a second request that actually sends the file), but if we're talking about users that know how to handle network-sniffers on their phone (needs root, AFAIK), you'll have bad luck, it's their device and their data that's trying to leave it after all :)You could try to use a secure connection to fix this.
What you could do :
Sign the file with your application
Check the signature on the server, check if the certificate is a certificate that is authorized
This will help a bit, but you'll still have the private key bundled with your application... someone may be able to find it and then sign modified files...
Another idea : can you compute the data or is it user generated ? If it's computed why not just compute the data and send it to the server (over SSL) without even writing it to the filesystem ?