I have a use case that requires the user to confirm device credential, and the createConfirmDeviceCredentialIntent method in KeyguardManager perfectly meets my need. However, this method was added since API 21.(reference link) So how can I achieve the same functionality before Android 5.0? I also want to support versions like Android 4.X.
Thanks!
Before 21 level this is certainly not possible on non-rooted device and there is no alternative with regular permissions.
If it is ok to require extra admin permissions, it is probably possible to emulate credential confirmation very loosely, with much more effort, by implementing DeviceAdminReceiver.onPasswordSucceeded. Lock the screen, when password succeeded perform the required action. This may turn out to be relatively complex because the action is not always received (only if status has changed), need to keep last success, communicate with receiver, etc.
As a side note, double check the use case and your design, in most cases when createConfirmDeviceCredentialIntent is used it is actually not required and other design choices may eliminate the need for it.
It was better to provide details of what exactly you are trying to protect. If it is a scenario for accidental access to the device by an unauthorized person and a permanent token is generated, say, from some oauth service, it may be reasonable either to reauthorize through the same service login flow or to store some hmac of original credentials along with token then prompt and re-validate credentials instead of prompting for device credentials. Alternatively, if that is enough for use case, you can use google login to authorize access to your app/token and verify google user is the same for the stored token.
The best answer I have seen for this situation is described in a blog post:
Android Secrets
However, it recreates system classes that are private and calls AOSP code that is not public. My bounty is for a better answer that would not require explicit Class naming inside the project. Perhaps Smart Lock or another awesome security library can be used for the backward compatibility I require.
Related
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.
I've got an app which shows user's contacts inside device and allows him to make a call.
I want to show my user the last calls he has made. I was using READ_CALL_LOG permission (and was reading call log) until Google restricted access to it, then I switched to ContactsProvider to retrieve contacts and sort them by LAST_TIME_CONTACTED but now Google says this column is deprecated and effectively it will have 0 value for new versions of Android OS (see https://developer.android.com/guide/topics/providers/contacts-provider#ObsoleteData)
My app is not a default dialer (only default dialers apps are allowed to access call log) so I was wondering how I can achieve what I want in Google Policy compliant way.
I tought about storing the last contacts selected inside my own database (I know it won't be a full call log, as I will only have access to calls made from my app but that's fine for me), but don't know whether it's compliant with G Policy. I wrote an email to Google, however the person who replied said he can't help me with my question and I have to create new version of my app and ask them for review.
Does anyone know if my idea about saving contacts in my own database is compliant with G policy (please provide links from official sites). From my link (which I've provided above) I can only see that Google says
If your apps are accessing or updating these fields or APIs, use
alternative methods. For example, you can fulfill certain use cases by
using private content providers or other data stored within your app
or backend systems.
However it doesn't convince me to whether my idea is compliant
Thanks for help!
I believe you may store and use any user actions that had happened within your app.
The purpose of the policy (as stated here: https://support.google.com/googleplay/android-developer/answer/9047303?hl=en) is to prevent apps from getting access to the call-log in order to make use of it for purposes other then what users' expect, that's why the emphasis on critical core functionality of the app.
In my experience, different Google reviewers tend to review the same app very differently, and while one may reject a certain use-case based on this policy, another might approve it.
I would suggest phrasing the screen you want to create in a way that will help the reviewer understand that this data was not acquired from the call-log but some app specific actions, so for example instead of title "Call Log" which might confuse some reviewers with the risk of rejecting this update, you should title it "Recent app actions" or something like that.
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?
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.
I have a paid android application which uses the google LVL code to authenticate users.
A company would like to pay me so that their application can include a free version of my application. However, I'm not sure how to accomplish this in a way that won't result in an easily pirated version of my app. Below are some implementation options I am considering, but none of them seem like particularly good ideas. Any suggestions?
I deliver them an apk which does not use the LVL code. They could then package my apk with their app, and install it using the ACTION_VIEW intent. This seems like a bad idea because I think it wouldn't be particularly hard for some rouge user to extract my unsecured apk and distribute it.
Maybe I could build a version that checks to see if their app is installed, and if it is it queries their app for some sort of unlock code. And app will only run if this unlock code succeeds. My main concern about this is that I have no idea if "querying another app" for an unlock code is accomplishable.
This is definitely accomplishable. As already said one way to query the app is by using a content provider. If you are concerned about security you can introduce additional permission that both apps must hold to access the provider. Although since it doubtfull that both apps have the same signature it won't be as effective.
Another way would be if they had a service that you could bind to and request a code or any other authentication. In this case their service can as well validate your apps validity by querying your apps userId and checking a signature via PackageManager.
Sad news is it's alomost impossible to prevent pirating your app anyway. Even with LVL... Since all this can be decompiled and eventually broken. But at least you can make attackers life harder.
For what you are looking to do I would create a jar out of your project and mark it as a library project. That way you can give your application out to your client but they wont be able to see the actual code you have written. Using this method they will be able to call any method directly which would be easier than having to interact with an apk.