android need google user id as part of method to unlock feature - android

My app is free and, using in-app purchases, I'd like to enable additional functionality. To do so, I am envisioning generating an unlock code that is dependent on the current user and the current app version. I need the first so that the same key won't work with someone else's installation (but will work for multiple devices owned by the same user). I may not need the second, but it would give a bit more future flexibility.
To do this, I need some sort of google user id. Is there such a thing? If so, how do I get it?
Thanks.

Google takes care of some of this for you. It will deliver a device dependent key to each device for a user. Your job is
1) Validate the key properly on your server
2) Make sure you return a device-specific authorization value from the server so users cannot just copy data files around.
3) On the device, use the authorization value to enable things.
Validating the key is easy but do make sure you do it on a server. The problem is identifying the device. Google and its partners dropped the ball a bit on that. Tim Bray has a blog article at http://android-developers.blogspot.ca/2011/03/identifying-app-installations.html that discusses the problem. I recommend using the ANDROID_ID despite his reservations. I have doubts about the security of his other proposal but haven't done a full analysis. Definitely stay away from anything network related (IMSI, IMEI, ESN, ...). I also cache the device identifier used and make sure it doesn't change.
Personally, I scramble the data needed to unlock my features in my app. When I get a valid transaction, I compute a key that can be combined with the device id to unlock the data. It is far from perfect but seems to work. I accept that I will be hacked - I just don't want it to be obvious.
If you want a per-version key, then you need to do a RESTORE_TRANSACTIONS and re-validate at the server any time the version changes.

I'd like to suggest another approach - no better, just different. Use a flag to indicate whether to allow or not running the upgrade features. Periodically validate with the in-app billing apis whether the user has purchased the upgrade. If not, reset the flag.
The user can hack the flag, but sooner or later it will be reset, blocking use of the features.
To truely break this method, the user would have to reverse engineer the code and bypass checking the flag. I doubt most people would bother with that, but what do I know?

Related

How to detect a user after reinstalling the app

I am creating an iOS and Android App and I want to create a screen where the player can start with a guest account or can connect his account with our own accountsystem.
But my question is: Can I detect a user after the app was uninstalled and installed again?
I know that there is something like the vendor. But this will change.
I know that other apps also can do this.
With the user's permission- have them log into an account. Or provide you with their google of facebook account info. So far as hardware ids, those are discouraged and actively being removed to prevent people from the API to prevent this.
Also remember- that unless the user logs in with an account, you don't really know whether it is the same person. You could know its the same phone, but you don't know if he gave it to his kid sister to play on. Or sold it when he got a new one, and now you've given the new owner access to someone else's account. Also, if you rely on hardware ids you won't know its me when I buy a new phone and download it on that.
So yeah- either have him log in with a username and password, or use a 3rd party signon mechanism like Google or Facebook.
For iOS, there is a recommended approach to do that: by using the DeviceCheck framework. The idea here is that it allows you to persist 2 bits of data across app installations on each device. You can set the first bit to 1 if the user has already installed the app or 0 otherwise. And use the second bit, for example, to check if the user has signed in or not.
The official documentation is pretty good, please check it out.
The downside of this approach is that you will also have to do some work on the backend side.
UPDATE:
If you specifically want to detect the account, there is no reliable approach. One of the options is to use identifierForVendor or generate some kind of device fingerprint (for example, by combining the device model, timezone, locale, etc.), but of course, this will not work every time.
Uniquely identifying a device is a security leak, and all platforms are putting serious restrictions on unique persistent identifiers because of privacy concerns.

Validation on server vs. validation on device

I'm currently trying to get the hang of in-app purchases on Android. I want to implement a non-consumable one-time product, i.e. allow perpetual access to all content in the app after purchasing the product.
In the Android developer guide for In-App-Billing there is a "Best practices" section (see https://developer.android.com/google/play/billing/billing_best_practices ).
It states: "It's highly recommended to validate purchase details on a server that you trust. [...] By implementing your signature verification logic on a server, you make it difficult for attackers to reverse-engineer your APK file."
I do not understand the logic behind this claim - assuming one does not have user accounts in the app.
Both methods seem to implement a signature check - either on the device or on a remote server.
I guess that the cracking tools that are available are able to scan for and disable the on device security check - so maybe this is meant by "making it difficult".
Otherwise I don't see a difference whether a reverse-engineer looks for the on-device check vs. looking for the server-roundtrip. Both calls can be be removed or replaced by an "always true" return value.
The best practices document also states: "verify that the orderId is a unique value that you have not previously processed".
Even this seems questionable to (for?) me.
Assuming that the reverse engineer is not able to find and replace the verification round-trip to the server and you keep track of all order ids on a remote server - they still are not tied to any user id. So how can you decide, whether
a user has switched devices (or lost his data) and is restoring purchases or
someone tries to gain access to paid content illegitimately?
(I guess you could check via heuristics - say allow 3 same order ids in X months, but there would always be the risk of blocking legitimate buyers.)
These questions appear to be rather basic to me - therefore I assume that I'm simply not getting the whole picture. I would be very thankful, if someone could shed some light on this.

Best approach to identify if user paid for an app on google play

I seem to have reached dead-end as to how may i create a proper model which plays well under a scenario that i have in mind.
The scenario is as follows; User purchases an application from Google play. At run-time i request user credentials (Google account associated with current device) which i then transfer to a web-service. At that point the back-end service tries to Auth user and identify if they have actually purchased the application in question and only then return any data relative to the request. (keep in mind that any request in general, as we are talking about a content based application, to the web-service at any point of the run-time life-cycle must always pass through the above pipe).
Now the reason for the above scenario being so specific is for the following reason;
-I would like everything to be managed by the end service rather than having any Auth process running natively as it may easily get bypassed. What i mean is that as long as anyone can decompile the application on their device, inspect the code, recompile it to their needs, have full access to any file if the device is rooted or even be allowed to clear any data related to the application by simply pressing the "clear data" option from android's application settings..... i do not see any other viable scenario other than the one i described above.
Now having said all of the above my problem is that it seems that Google does not like this specific scenario with both Google play developer api and Google+ api.
So i would really appreciate your comments, thoughts and any related materials you may have to offer in regards to the scenario i mentioned and ways to tackle down this problem.
I don't know of any such API that you can use. Why not try LVL, which would make sure that it's actually downloaded from the Android market? And if it's a paid app, the user must have definitely paid for it.
As far as decompiling is concerned, try Proguard. It's not 100% perfect solution, but it's pretty hard to break it.
Now, coming to the content. If you don't want anyone else to steal your content, then encrypt and save it. You can have a pretty good encryption mechanism that works with your web services, which would ensure that it's very very difficult to break.
What's wrong with using LVL and ProGuard? These tools were designed specifically to address your concerns with license verification and reverse engineering, respectively.
And, really don't worry too much about the one in a thousand people who might try to get your paid app for free. If your app is any good, then you'll be making plenty of sales anyway.
If I've read your proposal correctly, that sounds like a gross violation of your users' privacy and would definitely be a violation of Google's ToS. Why would your users give you their private credentials? They aren't supposed to be given to anyone, so why should they trust you or your systems with them? You would also be liable if you got hacked and credentials were stolen.

How to check if user paid on android?

I would like to use in-app billing in my android application (instead of creation 2 versions of application - free and pro). If user paid, then additional options in Preferences should be available.
My application synchronizes data with website (not my).
Each time synchronization happens, I would like to check if user paid or not.
How should I do it?
I think the easiest means for you would be to use Managed purchase. More on it is at http://developer.android.com/guide/market/billing/billing_admin.html#billing-purchase-type
The "manage by user account" purchase
type is useful if you are selling
items such as game levels or
application features. These items are
not transient and usually need to be
restored whenever a user reinstalls
your application, wipes the data on
their device, or installs your
application on a new device.
Update: website and API updated refer this now https://developer.android.com/google/play/billing/api.html
There are to many ways to do that, i will try and give you some of the most used
what about user accounts? can your application support users? if it does, its practically solved with 1 user per 1 account. just add a flag to your DB for each user. this is the most secure way, its very easy to know if someone is stealing from you thats why all MMO's (like WOW) use this type of check. you can easily know if theres more then one user on an account as well
the downside is that it requires more processing and some support is case someone's account gets stolen or other user support of that kind.
you can save a sort of key inside your application. and some other key on the server. if the key matches (either 1 to 1 or after some manipulation) then you have yourself a paid user, other you dont.when someone buys the application then change the key on the device.
just do what you dont want to do and have 2 applications for free and paid it will probably be less work then the other 2 list above.
there are many ways of doing what you want. but i'll tell you this:
most applications use method 2 but on the opposite direction, meaning serial key.
i dont think your gonna create an mmo so theres no need for option 1 unless you really dont want anyone hacking your application (which i assume no matter what you do it will be hacked in todays world. i'll advice you to trust those who pay and accept those who dont)
method 3 is just easy in my opinion especialy when you want to just remove menu options, but it also creates duplicate repositories for code.
good luck. what ever you decide is good, make a theft protection, if someone wants to steal it, they will, dont fight it (even PS3 got hacked in the end)

Webservice for Android Market purchases

As Google stores your purchases of Android apps, I was wondering if they are somehow offering a webservice that can be used to check if a certain app has been purchased. To me this seems the most secure way of distinguishing free and paid users from within my app.
It would not only defeat piracy, but would also allow for managing a database of legally registered users, by a one-time check through this service.
What are your solutions to this matter?
Google provides a library for you. See here.
Note that this has been compromised in unprotected apps, so you should use something like ProGuard. The link above contains more information.
Finally, keep in mind that the Android Market is not the only app market for Android out there. Amazon has their own DRM.
At this particular moment there is one way to check.
The Android Market authenticates purchases through Google Checkout, but Google has not implemented the Checkout API to synchronize Market purchases. So calls like that check the status of an order do not work. Maybe Google doesn't want dev's to get a hold of customer emails? Either way, I do not know why it does not exist, it seems to me that if Google simply made this service available we could implement a far more superior security system that would better utilize the methods of obfuscation. As it is at the moment, a hacker can simply look for a specific class like the ILicenceService and hook it.
The only way at the current moment is to download a list of current purchases. You can do this using an authenticated http call. The drawbacks to doing this are pretty large though. First, the list it provides only extends back 31 days (so you've got to make sure you keep everything). Second, you would have to call and parse at least every ten minutes. Actually faster than that, most users want to play their games when they buy them. Third, if your service, or server goes down, that is precious information that is being requested almost instantly by your users.
I don't know how many dev's are currently utilizing this process, I considered it, but am just going to keep complaining to Google for a better method.
You could piggy back off of the LVL. I have just implemented a similar system.
Perform Check via LVL.
On success make a post to your own web server and store whatever details you need, i.e. DeviceID etc.
You could also perform checks to your own server even when the LVL check fails and allow things like trial periods etc.

Categories

Resources