I have this app developed and issued to users via USB. But I want to prevent them from extract the APK and install it on other phones.
Currently, I have a APK signing signature check when the app launches and prevent it from running if it doesn't match mine. But it doesn't to stop those APK extractor apps, this one for example.
https://play.google.com/store/apps/details?id=com.ext.ui&hl=en
I checked the extracted APK and it has the same signature as my original! Is there any other ways to stop it?
My app is a standalone app so it doesn't have a server to talk to...Thanks!
Disclaimer! There's no way you can protect your app 100% but you can try the following ways:
Google Play Licensing and the License Verification Library (LVL)
This service allows your app query a Google Play Licensing server to determine if currently running device is recorded as a purchaser.
More info
OBFUSCATION
Eliminate all chances of reverse engineering which is a way of generating an apk from your app.
More info
COPY PROTECTION
Although superseded by licensing on some platforms (most notably Android), copy protection is a simple way of fending off more perfunctory attempts at piracy.
Digital rights management (DRM) can be built into the app itself, be part of the app store to which it is uploaded (such as Amazon DRM), or purchased as part of a third-party paid DRM service.
In general you can not prevent your app from being extracted from a device. Furthermore any of your user could simple upload the retrieved APK file somewhere on the net.
Therefore you can only protect your app from being used by "the wrong people". I see two possible solutions for doing so:
Dongle the version to a specific device
You know the principle by many shareware software: After installing the app requires to enter a license code that activates it. The license code is generated by you after receiving some sort of device fingerprint and the app checks if the license is valid for this specific device.
Embed a water-mark that allows you to identify who has leaked the APK
This would require to create unique APK files for each of your legitimate user.
Related
I want to check and allow the use of my app just if it has been downloaded from the Play store, and it has not been shared by other user or from any other source. How can I prevent an user to use the app if it has not been downloaded from the Google Play store?
This method will check if your app has been installed from the Play Store.
boolean verifyInstallerId(Context context) {
// A list with valid installers package name
List<String> validInstallers = new ArrayList<>(Arrays.asList("com.android.vending", "com.google.android.feedback"));
// The package name of the app that has installed your app
final String installer = context.getPackageManager().getInstallerPackageName(context.getPackageName());
// true if your app has been downloaded from Play Store
return installer != null && validInstallers.contains(installer);
}
Some days ago I released an Android library, PiracyChecker, that protects your app using some techniques, such as Google Play Licensing (LVL), APK signature protection and installer ID (this one).
Bypass the Check
I want to check and allow the use of my app just if it has been downloaded from the Play store, and it has not been shared by other user or from any other source.
While this check is possible to achieve programmatically its also possible to bypass by repackaging the app without the check or by using an instrumentation framework at runtime to bypass the check. An example of such a framework is Frida:
Inject your own scripts into black box processes. Hook any function, spy on crypto APIs or trace private application code, no source code needed. Edit, hit save, and instantly see the results. All without compilation steps or program restarts.
I wrote an article to show how to use Frida to bypass certificate pinning in an Android app, and the same approach can be used to bypass this check. The only difference is that you need to find the correct Frida script or write yourself one and use it in place of the on to bypass pinning. The Frida Code Share website as a huge set of scripts and one may exist for this propose or can be used as a starting point to see how to write your own script.
Protect the Check
How can I prevent an user to use the app if it has not been downloaded from the Google Play store?
So, if you use the built-in context.getPackageManager().getInstallerPackageName(context.getPackageName()); or any other method you will be safeguarded against normal users that do not install your mobile app from the Google play store, but anyone wanting to attack your mobile app will have several ways of bypassing this protection as I mention above.
A possible to solution to protect your mobile app against attackers bypassing your check is to use Runtime Self Defense Protections or a Mobile App Attestion solution, and I recommend you to read this answer, especially the sections Hardening and Shielding the Mobile App, Securing the API Server and A Possible Better Solution to see how you can prevent your mobile app to work properly when its not your genuine mobile app.
Do You Want To Go The Extra Mile?
In any response to a security question I always like to reference the excellent work from the OWASP foundation.
For Mobile Apps
OWASP Mobile Security Project - Top 10 risks
The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.
OWASP - Mobile Security Testing Guide:
The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.
com.android.vending is the play store package name,
context.packageManager.getInstallerPackageName(context.packageName) gets you the source package name.
Other source such as Huawei App Gallery to download the app. But i am not sure what its package name
Just for completeness: client-server applications (apps communicating with your own server) should use Server-Side License Verification to check that the app was installed from GP and is valid - License Verification Library (LVL) will be responsible for this.
This can be used to protect backend servers from not legitimate clients, such as bots, which will have to pass LVL verification first, before getting access to other backend functionality.
Scenario:
Someone buys/downloads my apps from the play store.
They then do an adb pull /data/app/com.example.myapp.apk on my apps
They then sideload it on another device/distribute it online
Can I:
Via my app identify it was not legitimately purchased/downloaded?
Download my apps from said website and verify the same person downloaded them?
Find any identifying information/user data inside the apk?
I can only answer number 3:
Reading: https://android.stackexchange.com/a/28138
It seems no user data will be in the APK, I don't know about the play store data though.
Can I:
Via my app identify it was not legitimately purchased/downloaded?
It depends how your app can be purchased. But even then that will be pretty hard to do that, especially this will be prone to spoofing on rooted devices, so if your app is a standalone product and does not require any account on your servers to be used, then it may be really painful and at some point not worth the efforts maybe.
Download my apps from said website and verify the same person downloaded them?
No.
Find any identifying information/user data inside the apk?
No. There's none.
Via my app identify it was not legitimately purchased/downloaded?
Aside from the security key which guarantees that the contents of the apk are not tampered with, the apk on it's own does not identify where it came from. If you need extra security measures against pirating, you have to look for other solutions, e.g. account checking, web-based identification, etc
Download my apps from said website and verify the same person downloaded them?
If you mean that whether Google Play will identify you as the person that originally purchased the app, the answer is no. If the app is paid Google Play will realize that you have not paid for it. If the app is not paid then Google Play will simply add that to the library of apps that you have and/or installed
Find any identifying information/user data inside the apk?
There is no user data in the apk since the apk is the same file for any device that installs it. However, some apps might store data locally which means that through adb pull an untrusted party might be able to pull your user data from your phone. Most apps don't store anything locally because of this.
I want to check and allow the use of my app just if it has been downloaded from the Play store, and it has not been shared by other user or from any other source. How can I prevent an user to use the app if it has not been downloaded from the Google Play store?
This method will check if your app has been installed from the Play Store.
boolean verifyInstallerId(Context context) {
// A list with valid installers package name
List<String> validInstallers = new ArrayList<>(Arrays.asList("com.android.vending", "com.google.android.feedback"));
// The package name of the app that has installed your app
final String installer = context.getPackageManager().getInstallerPackageName(context.getPackageName());
// true if your app has been downloaded from Play Store
return installer != null && validInstallers.contains(installer);
}
Some days ago I released an Android library, PiracyChecker, that protects your app using some techniques, such as Google Play Licensing (LVL), APK signature protection and installer ID (this one).
Bypass the Check
I want to check and allow the use of my app just if it has been downloaded from the Play store, and it has not been shared by other user or from any other source.
While this check is possible to achieve programmatically its also possible to bypass by repackaging the app without the check or by using an instrumentation framework at runtime to bypass the check. An example of such a framework is Frida:
Inject your own scripts into black box processes. Hook any function, spy on crypto APIs or trace private application code, no source code needed. Edit, hit save, and instantly see the results. All without compilation steps or program restarts.
I wrote an article to show how to use Frida to bypass certificate pinning in an Android app, and the same approach can be used to bypass this check. The only difference is that you need to find the correct Frida script or write yourself one and use it in place of the on to bypass pinning. The Frida Code Share website as a huge set of scripts and one may exist for this propose or can be used as a starting point to see how to write your own script.
Protect the Check
How can I prevent an user to use the app if it has not been downloaded from the Google Play store?
So, if you use the built-in context.getPackageManager().getInstallerPackageName(context.getPackageName()); or any other method you will be safeguarded against normal users that do not install your mobile app from the Google play store, but anyone wanting to attack your mobile app will have several ways of bypassing this protection as I mention above.
A possible to solution to protect your mobile app against attackers bypassing your check is to use Runtime Self Defense Protections or a Mobile App Attestion solution, and I recommend you to read this answer, especially the sections Hardening and Shielding the Mobile App, Securing the API Server and A Possible Better Solution to see how you can prevent your mobile app to work properly when its not your genuine mobile app.
Do You Want To Go The Extra Mile?
In any response to a security question I always like to reference the excellent work from the OWASP foundation.
For Mobile Apps
OWASP Mobile Security Project - Top 10 risks
The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.
OWASP - Mobile Security Testing Guide:
The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.
com.android.vending is the play store package name,
context.packageManager.getInstallerPackageName(context.packageName) gets you the source package name.
Other source such as Huawei App Gallery to download the app. But i am not sure what its package name
Just for completeness: client-server applications (apps communicating with your own server) should use Server-Side License Verification to check that the app was installed from GP and is valid - License Verification Library (LVL) will be responsible for this.
This can be used to protect backend servers from not legitimate clients, such as bots, which will have to pass LVL verification first, before getting access to other backend functionality.
Suppose I have a wifi network with a walled garden that prevents users from accessing Internet unless an authentication procedure is performed via browser.
Suppose I have an application on Google Play that automates this process for inexperienced people. And suppose 95% of users are inexperienced and unwilling to perform SMS-OTP authentication on a site that is not optimized for mobile.
Scenario
A person asks a clerk how to connect to internet using Android. The clerk suggests the person to download the Android app, but the person responds he has no Internet access because he has no 3G data plan.
Possible workaround
The walled garden portal detects the device running Android by user agent and says: "Would you like to download an APK from our internal network without having to go to Google Play?". The user accepts, unlocks unknown sources and installs the app.
Question
In this scenario, if a user downloads an APK of a Google Play-available application, signed with same key, on his device, will the installed application be linked to Play and subject to updates? And I mean without using a Market linker app.
That's my old answer, don't read it, just skip to the edit portion:
Short answer is no!
I'm sure there're geeky ways around to link an app to its Google Play
variant, but your scenario of non-geeky customers I reckon the best
option is to program the network to allow Android mobile access
(checking the user agent) to play.google.com (maybe even from the
redirection website auto-launch the google play link direct to said
app).
edit:
I'm thinking a bit more on this problem and I would like to change my answer to "I don't know" (what a horrible answer). But I would like to propose a test that you can do it yourself.
The reason I'm changing the answer is because I remember now apps like Titanium and they do link the app to the Play whenever restoring a backup. Of course, Titanium needs root, but that's because it's messing with other apps, not its own.
So in light of what I discusse I'll suggest you a simple test:
build an app, anything, Hello world!
Upload this app to Google Play and make it active
Wait a few hours for Google servers to make it available
Manually flash the same build version (with exact same signing key, etc) to a device.
Reboot the device (to be sure the system will read through installed applications and do communication with Google Play)
Go to Google Play on the device and check if it shows the app
It's possible that the app have the same package name and signed with the same key, the Google Play on the device itself will recognise it as the same and link it.
I'm totally new to the Android Play store. I'm working on an app that is almost finished and ready to publish.
But I notice that you can copy the apk file (after purchase) to another location (sd card for example) and install it on another device. That is something I want to avoid.
My questions are:
Does the Google Play store sign the apk file with some unique id before downloading? If is true, can I read/get this code from the
apk?
Is it possible to know the email-address of the user that purchase the app or can I access some other details of the user?
Is it possible to get an unique detail of the device?
Is there another solution available to protect the copy of the apk?
I want to create a registration method that binds the device to the app, so when the user tried to copy the app, it is not possible to use it. Is this all possible?
If you have any questions, let me know.
PS: I used Adobe Flash Builder to build the app.
Your best bet is a combination of LVL (Android License Verification Library) and tracking device installations.
LVL
http://developer.android.com/guide/market/licensing/index.html
Tracking Device installations
http://android-developers.blogspot.in/2011/03/identifying-app-installations.html
To verify that the user has paid there is a Google Play Licensing service, you can use it. There are copy protection mechanisms on Google Play if you choose to use them, but they are deprecated now since you are supposed to use the service I just mentioned. You can gather some unique device details, there are APIs to do that, but this is not really needed.